use of org.sablo.websocket.TypedData in project servoy-client by Servoy.
the class FormElement method propertiesForTemplateJSON.
public TypedData<Map<String, Object>> propertiesForTemplateJSON() {
Map<String, Object> properties = new HashMap<>();
WebObjectSpecification componentSpec = getWebComponentSpec();
Map<String, PropertyDescription> propDescription = componentSpec.getProperties();
for (PropertyDescription pd : propDescription.values()) {
Object val = getRawPropertyValue(pd.getName());
properties.put(pd.getName(), val);
}
if (persistImpl == null || !persistImpl.isForm()) {
Dimension dim = getDesignSize();
if (dim != null)
properties.put(StaticContentSpecLoader.PROPERTY_SIZE.getPropertyName(), dim);
Integer anchor = (Integer) getPropertyValue(StaticContentSpecLoader.PROPERTY_ANCHORS.getPropertyName());
if (anchor != null) {
properties.put(StaticContentSpecLoader.PROPERTY_ANCHORS.getPropertyName(), anchor);
}
}
Object offsetY = getPropertyValue("offsetY");
if (offsetY != null)
properties.put("offsetY", offsetY);
Object partHeight = getPropertyValue("partHeight");
if (partHeight != null)
properties.put("partHeight", partHeight);
Object formview = getPropertyValue("formview");
if (formview != null)
properties.put("formview", formview);
// get types for conversion
PropertyDescriptionBuilder propertyTypes = AggregatedPropertyType.newAggregatedPropertyBuilder();
for (Entry<String, Object> p : properties.entrySet()) {
PropertyDescription t = getWebComponentSpec().getProperty(p.getKey());
if (t != null)
propertyTypes.withProperty(p.getKey(), t);
}
PropertyDescription pd = propertyTypes.build();
return new TypedData<>(properties, pd.hasChildProperties() ? pd : null);
}
use of org.sablo.websocket.TypedData in project servoy-client by Servoy.
the class ComponentTypeSabloValue method browserUpdatesReceived.
public void browserUpdatesReceived(Object jsonValue) {
if (childComponent == null)
return;
try {
JSONArray updates = (JSONArray) jsonValue;
for (int i = 0; i < updates.length(); i++) {
JSONObject update = (JSONObject) updates.get(i);
if (update.has("handlerExec")) {
// { handlerExec: {
// eventType: ...,
// args: ...,
// rowId : ...
// }});
update = update.getJSONObject("handlerExec");
if (update.has("eventType")) {
boolean selectionOk = true;
if (update.has("rowId")) {
String rowId = update.optString("rowId");
if (rowId != null) {
FoundsetTypeSabloValue foundsetValue = getFoundsetValue();
if (foundsetValue != null) {
if (!foundsetValue.setEditingRowByPkHash(rowId)) {
Debug.error("Cannot select row when component event was fired; row identifier: " + rowId + ", forFoundset: '" + foundsetValue + "', component: " + (childComponent != null ? childComponent : getName()));
selectionOk = false;
}
}
}
}
if (selectionOk) {
String eventType = update.getString("eventType");
// String beanName = update.getString("beanName");
JSONArray jsargs = update.getJSONArray("args");
Object[] args = new Object[jsargs == null ? 0 : jsargs.length()];
for (int j = 0; jsargs != null && j < jsargs.length(); j++) {
args[j] = jsargs.get(j);
}
Object result = null;
String error = null;
try {
result = childComponent.executeEvent(eventType, args);
} catch (ParseException pe) {
log.warn("Warning: " + pe.getMessage(), pe);
} catch (IllegalChangeFromClientException ilcae) {
log.warn("Warning: " + ilcae.getMessage());
} catch (Exception e) {
error = "Error: " + e.getMessage();
log.error(error, e);
}
int cmsid = update.optInt("defid", -1);
if (cmsid != -1) {
if (error == null) {
Object resultObject = result;
PropertyDescription objectType = null;
if (result instanceof TypedData) {
resultObject = ((TypedData<?>) result).content;
objectType = ((TypedData<?>) result).contentType;
}
CurrentWindow.get().getSession().getSabloService().resolveDeferedEvent(cmsid, true, resultObject, objectType);
} else {
CurrentWindow.get().getSession().getSabloService().resolveDeferedEvent(cmsid, false, error, null);
}
}
}
}
} else if (update.has("propertyChanges")) {
// { propertyChanges : {
// prop1: ...,
// prop2: ...
// }}
JSONObject changes = update.getJSONObject("propertyChanges");
Iterator<String> keys = changes.keys();
while (keys.hasNext()) {
String key = keys.next();
Object object = changes.get(key);
childComponent.putBrowserProperty(key, object);
}
} else if (update.has(ViewportDataChangeMonitor.VIEWPORT_CHANGED)) {
// component is linked to a foundset and the value of a property that depends on the record changed client side;
// in this case update DataAdapterList with the correct record and then set the value on the component
FoundsetTypeSabloValue foundsetPropertyValue = getFoundsetValue();
if (foundsetPropertyValue != null && foundsetPropertyValue.getFoundset() != null) {
JSONObject change = update.getJSONObject(ViewportDataChangeMonitor.VIEWPORT_CHANGED);
String rowIDValue = change.getString(FoundsetTypeSabloValue.ROW_ID_COL_KEY);
String propertyName = change.getString(FoundsetTypeSabloValue.DATAPROVIDER_KEY);
Object value = change.get(FoundsetTypeSabloValue.VALUE_KEY);
updatePropertyValueForRecord(foundsetPropertyValue, rowIDValue, propertyName, value);
foundsetPropertyValue.setDataAdapterListToSelectedRecord();
} else {
Debug.error("Component updates received for record linked property, but component is not linked to a foundset: " + update.get(ViewportDataChangeMonitor.VIEWPORT_CHANGED));
}
} else if (update.has("svyApply")) {
// { svyApply: {
// rowId: rowId, // only when linked to foundset
// propertyName: property,
// propertyValue: propertyValue
// }}
JSONObject changeAndApply = update.getJSONObject("svyApply");
String propertyName = changeAndApply.getString(ComponentPropertyType.PROPERTY_NAME_KEY);
Object value = changeAndApply.get(ComponentPropertyType.VALUE_KEY);
try {
if (forFoundsetTypedPropertyName != null && recordBasedProperties.contains(propertyName)) {
// changes component record and sets value
String rowIDValue = changeAndApply.getString(FoundsetTypeSabloValue.ROW_ID_COL_KEY);
foundsetLinkedPropOfComponentValueChangeHandler.setApplyingDPValueFromClient(true);
FoundsetTypeSabloValue foundsetValue = getFoundsetValue();
updatePropertyValueForRecord(foundsetValue, rowIDValue, propertyName, value);
// apply change to record/dp
foundsetValue.getDataAdapterList().pushChanges(childComponent, propertyName);
foundsetValue.setDataAdapterListToSelectedRecord();
} else {
childComponent.putBrowserProperty(propertyName, value);
IWebFormUI formUI = getParentComponent().findParent(IWebFormUI.class);
// apply change to record/dp
formUI.getDataAdapterList().pushChanges(childComponent, propertyName);
}
if (forFoundsetTypedPropertyName != null && !recordBasedProperties.contains(propertyName)) {
// a global or form var that in case of a foundset linked component will apply the value on the child component but, as it knows it is comming from the browser,
// the child component will not notify it as a changed value; we need that though as we need to resend that value for all rows back to client, not just currently selected one
childComponent.markPropertyAsChangedByRef(propertyName);
}
} finally {
if (foundsetLinkedPropOfComponentValueChangeHandler != null)
foundsetLinkedPropOfComponentValueChangeHandler.setApplyingDPValueFromClient(false);
}
} else if (update.has("svyStartEdit")) {
// { svyStartEdit: {
// rowId: rowId, // only if linked to foundset
// propertyName: property
// }}
JSONObject startEditData = update.getJSONObject("svyStartEdit");
String propertyName = startEditData.getString(ComponentPropertyType.PROPERTY_NAME_KEY);
IDataAdapterList dal;
if (forFoundsetTypedPropertyName != null && recordBasedProperties.contains(propertyName)) {
String rowIDValue = startEditData.getString(FoundsetTypeSabloValue.ROW_ID_COL_KEY);
IFoundSetInternal foundset = getFoundsetValue().getFoundset();
dal = getFoundsetValue().getDataAdapterList();
Pair<String, Integer> splitHashAndIndex = FoundsetTypeSabloValue.splitPKHashAndIndex(rowIDValue);
if (foundset != null) {
int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
if (recordIndex != -1) {
((FoundsetDataAdapterList) dal).setRecordQuietly(foundset.getRecord(recordIndex));
} else {
Debug.error("Cannot find record for foundset linked record dependent component property - startEdit (" + rowIDValue + "); property '" + propertyName, new RuntimeException());
}
} else {
Debug.error("Foundset is null while trying to startEdit for foundset linked record dependent component property (" + rowIDValue + "); property '" + propertyName, new RuntimeException());
}
} else {
IWebFormUI formUI = getParentComponent().findParent(IWebFormUI.class);
dal = formUI.getDataAdapterList();
}
// TODO last arg should be here the foundsetLinked row Id in case the property is itself a foundset-linked DP; this should be done as part of case SVY-10500
dal.startEdit(childComponent, propertyName, null);
}
}
} catch (Exception ex) {
Debug.error(ex);
}
}
use of org.sablo.websocket.TypedData in project servoy-client by Servoy.
the class NGClient method executeMethod.
/*
* @see org.sablo.websocket.IServerService#executeMethod(java.lang.String, org.json.JSONObject)
*/
@Override
public Object executeMethod(String methodName, JSONObject args) throws Exception {
switch(methodName) {
case "login":
try {
credentials.setUserName(args.optString("username"));
credentials.setPassword(args.optBoolean("encrypted") ? SecuritySupport.decrypt(Settings.getInstance(), args.optString("password")) : args.optString("password"));
authenticate(null, null, new Object[] { credentials.getUserName(), credentials.getPassword() });
if (getClientInfo().getUserUid() != null) {
wsSession.getEventDispatcher().postEvent(new Runnable() {
public void run() {
try {
loadSolution(getSolution().getName());
} catch (RepositoryException ex) {
Debug.error(ex);
}
}
});
if (args.optBoolean("remember")) {
JSONObject r = new JSONObject();
r.put("username", credentials.getUserName());
r.put("password", SecuritySupport.encrypt(Settings.getInstance(), credentials.getPassword()));
return r;
} else
return Boolean.TRUE;
}
} catch (Exception ex) {
Debug.error(ex);
}
return Boolean.FALSE;
case "autosave":
getFoundSetManager().getEditRecordList().stopEditing(false);
break;
case "callServerSideApi":
{
String serviceScriptingName = args.getString("service");
PluginScope scope = (PluginScope) getScriptEngine().getSolutionScope().get("plugins", getScriptEngine().getSolutionScope());
Object service = scope.get(serviceScriptingName, scope);
if (service instanceof WebServiceScriptable) {
WebServiceScriptable webServiceScriptable = (WebServiceScriptable) service;
JSONArray methodArguments = args.getJSONArray("args");
String serviceMethodName = args.getString("methodName");
// apply browser to sablo java value conversion - using server-side-API definition from the service's spec file if available (otherwise use default conversion)
// the call to webServiceScriptable.executeScopeFunction will do the java to Rhino one
// find spec for method
// get specification from plugins scope (which uses getScriptName() of service, then use the getClientService using the real name, to make sure client service is created if needed)
WebObjectSpecification serviceSpec = webServiceScriptable.getServiceSpecification();
BaseWebObject serviceWebObject = (BaseWebObject) getWebsocketSession().getClientService(serviceSpec.getName());
WebObjectFunctionDefinition functionSpec = (serviceSpec != null ? serviceSpec.getInternalApiFunction(serviceMethodName) : null);
if (functionSpec == null) {
functionSpec = (serviceSpec != null ? serviceSpec.getApiFunction(serviceMethodName) : null);
}
List<PropertyDescription> argumentPDs = (functionSpec != null ? functionSpec.getParameters() : null);
// apply conversion
Object[] arrayOfJavaConvertedMethodArgs = new Object[methodArguments.length()];
for (int i = 0; i < methodArguments.length(); i++) {
arrayOfJavaConvertedMethodArgs[i] = JSONUtils.fromJSON(null, methodArguments.get(i), (argumentPDs != null && argumentPDs.size() > i) ? argumentPDs.get(i) : null, new BrowserConverterContext(serviceWebObject, PushToServerEnum.allow), new ValueReference<Boolean>(false));
}
Object retVal = webServiceScriptable.executeScopeFunction(functionSpec, arrayOfJavaConvertedMethodArgs);
if (functionSpec != null && functionSpec.getReturnType() != null) {
// this means that when this return value is sent to client it will be converted to browser JSON correctly - if we give it the type
retVal = new TypedData<Object>(retVal, functionSpec.getReturnType());
}
return retVal;
} else {
Debug.warn("callServerSideApi for unknown service '" + serviceScriptingName + "'");
}
break;
}
}
return null;
}
use of org.sablo.websocket.TypedData in project servoy-client by Servoy.
the class ComponentPropertyType method toTemplateJSONValue.
@Override
public JSONWriter toTemplateJSONValue(final JSONWriter writer, String key, ComponentTypeFormElementValue formElementValue, PropertyDescription pd, DataConversion conversionMarkers, final FormElementContext formElementContext) throws JSONException {
if (formElementValue == null)
return writer;
FlattenedSolution clientFlattenedSolution = (formElementContext != null && formElementContext.getContext() != null) ? formElementContext.getContext().getSolution() : null;
if (!formElementValue.isSecurityViewable(clientFlattenedSolution)) {
return writer;
}
// so that the client knows it must use the custom client side JS for what JSON it gets
if (conversionMarkers != null)
conversionMarkers.convert(ComponentPropertyType.TYPE_NAME);
// create children of component as specified by this property
final FormElementContext feContext = new FormElementContext(formElementValue.element, formElementContext.getContext(), null);
JSONUtils.addKeyIfPresent(writer, key);
writer.object();
writeTemplateJSONContent(writer, formElementValue, forFoundsetTypedPropertyName(pd), feContext, new IModelWriter() {
@Override
public void writeComponentModel() throws JSONException {
// TODO here we could remove record based props from fe.propertiesForTemplateJSON(); but normally record based props will not write any value in template anyway
TypedData<Map<String, Object>> modelProperties = feContext.getFormElement().propertiesForTemplateJSON();
writer.object();
JSONUtils.writeDataWithConversions(FormElementToJSON.INSTANCE, writer, modelProperties.content, modelProperties.contentType, feContext);
writer.endObject();
}
}, formElementValue.recordBasedProperties, true);
writer.endObject();
return writer;
}
Aggregations