use of org.sablo.specification.WebObjectFunctionDefinition in project servoy-client by Servoy.
the class WebServiceScriptable method has.
@Override
public boolean has(String name, Scriptable start) {
PropertyDescription desc = serviceSpecification.getProperty(name);
if (desc != null) {
IWebObjectContext service = (IWebObjectContext) application.getWebsocketSession().getClientService(serviceSpecification.getName());
IPropertyType<?> type = desc.getType();
// it is available by default, so if it doesn't have conversion, or if it has conversion and is explicitly available
return !(type instanceof ISabloComponentToRhino<?>) || ((ISabloComponentToRhino) type).isValueAvailableInRhino(service.getProperty(name), desc, service);
}
WebObjectFunctionDefinition apiFunction = serviceSpecification.getApiFunction(name);
if (apiFunction != null)
return true;
return application.getWebsocketSession().getClientService(serviceSpecification.getName()).getProperties().content.containsKey(name);
}
use of org.sablo.specification.WebObjectFunctionDefinition in project servoy-client by Servoy.
the class WebServiceScriptable method put.
@Override
public void put(String name, Scriptable start, Object value) {
PropertyDescription desc = serviceSpecification.getProperty(name);
BaseWebObject service = (BaseWebObject) application.getWebsocketSession().getClientService(serviceSpecification.getName());
if (desc != null) {
Object previousVal = service.getProperty(name);
Object val = NGConversions.INSTANCE.convertRhinoToSabloComponentValue(value, previousVal, desc, service);
if (val != previousVal)
service.setProperty(name, val);
} else {
WebObjectFunctionDefinition apiFunction = serviceSpecification.getApiFunction(name);
// don't allow api to be overwritten.
if (apiFunction != null)
return;
// TODO conversion should happen from string (color representation) to Color object.
// DesignConversion.toObject(value, type)
service.setProperty(name, value);
}
}
use of org.sablo.specification.WebObjectFunctionDefinition in project servoy-client by Servoy.
the class RuntimeWebComponent method get.
@Override
public Object get(final String name, final Scriptable start) {
if (specProperties != null && specProperties.contains(name)) {
PropertyDescription pd = webComponentSpec.getProperties().get(name);
if (WebFormComponent.isDesignOnlyProperty(pd))
return Scriptable.NOT_FOUND;
return NGConversions.INSTANCE.convertSabloComponentToRhinoValue(component.getProperty(name), pd, component, start);
}
if ("getFormName".equals(name)) {
return new Callable() {
@Override
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
IWebFormUI parent = component.findParent(IWebFormUI.class);
if (parent != null) {
return parent.getController().getName();
}
return null;
}
};
}
if ("getDesignTimeProperty".equals(name) && component.getFormElement().getPersistIfAvailable() instanceof AbstractBase) {
return new Callable() {
@Override
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
return Utils.parseJSExpression(((AbstractBase) component.getFormElement().getPersistIfAvailable()).getCustomDesignTimeProperty((String) args[0]));
}
};
}
if ("getDesignProperties".equals(name) && component.getFormElement().getPersistIfAvailable() instanceof AbstractBase) {
return new Callable() {
@Override
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
Map<String, Object> designProperties = ((AbstractBase) component.getFormElement().getPersistIfAvailable()).getMergedCustomDesignTimeProperties();
Map<String, Object> parsedMap = new HashMap<String, Object>();
designProperties.entrySet().forEach(entry -> {
parsedMap.put(entry.getKey(), Utils.parseJSExpression(entry.getValue()));
});
return parsedMap;
}
};
}
final Function func = apiFunctions.get(name);
if (func != null && isApiFunctionEnabled(name)) {
final List<Pair<String, String>> oldVisibleForms = getVisibleForms();
return new BaseFunction() {
@Override
public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
Object retValue;
cx.putThreadLocal(SERVER_SIDE_SCRIPT_EXECUTE, Boolean.TRUE);
try {
retValue = func.call(cx, scope, thisObj, args);
} finally {
cx.removeThreadLocal(SERVER_SIDE_SCRIPT_EXECUTE);
}
if (!(func instanceof WebComponentFunction)) {
WebObjectFunctionDefinition def = webComponentSpec.getApiFunctions().get(name);
retValue = NGConversions.INSTANCE.convertServerSideRhinoToRhinoValue(retValue, def.getReturnType(), component, null);
}
updateVisibleContainers(oldVisibleForms);
return retValue;
}
};
}
// check if we have a setter/getter for this property
if (name != null && name.length() > 0) {
String uName = new StringBuffer(name.substring(0, 1).toUpperCase()).append(name.substring(1)).toString();
if (apiFunctions.containsKey("set" + uName) && apiFunctions.containsKey("get" + uName)) {
// call getter
Function propertyGetter = apiFunctions.get("get" + uName);
return propertyGetter.call(Context.getCurrentContext(), start, start, new Object[] {});
}
}
if ("svyMarkupId".equals(name)) {
String formName = null;
IWebFormUI parent = component.findParent(IWebFormUI.class);
if (parent != null) {
formName = parent.getController().getName();
} else {
formName = component.getFormElement().getForm().getName();
}
return ComponentFactory.getMarkupId(formName, component.getName());
}
// is this really needed? will not prototype be looked at automatically by Rhino code?
if (prototypeScope != null) {
return prototypeScope.get(name, start);
}
return Scriptable.NOT_FOUND;
}
use of org.sablo.specification.WebObjectFunctionDefinition in project servoy-client by Servoy.
the class WebFormController method notifyVisible.
@Override
public boolean notifyVisible(boolean visible, List<Runnable> invokeLaterRunnables) {
if (isFormVisible == visible)
return true;
if (!visible && destroyOnHide) {
Runnable run = new Runnable() {
public void run() {
destroy();
}
};
invokeLaterRunnables.add(run);
}
boolean notifyVisibleSuccess = super.notifyVisible(visible, invokeLaterRunnables);
if (notifyVisibleSuccess) {
for (WebComponent comp : getFormUI().getComponents()) {
RuntimeWebComponent runtimeComponent = getFormUI().getRuntimeWebComponent(comp.getName());
if (runtimeComponent != null) {
WebObjectFunctionDefinition function = null;
if (visible)
function = comp.getSpecification().getInternalApiFunction("onShow");
else
function = comp.getSpecification().getInternalApiFunction("onHide");
if (function != null) {
runtimeComponent.executeScopeFunction(function, new Object[0]);
}
}
}
}
if (visible && !isFormVisible) {
// note: the show operation (visible = true in if above) of a form cannot be denied, so we can update things before the call to super.notifyVisible below
for (WebComponent comp : getFormUI().getComponents()) {
if ((comp instanceof WebFormComponent) && ((WebFormComponent) comp).getFormElement().getPersistIfAvailable() instanceof TabPanel) {
Object visibleTabPanel = comp.getProperty("visible");
if (visibleTabPanel instanceof Boolean && !((Boolean) visibleTabPanel).booleanValue())
continue;
Object tabIndex = comp.getProperty("tabIndex");
Object tabs = comp.getProperty("tabs");
if (tabs instanceof List && ((List) tabs).size() > 0) {
List tabsList = (List) tabs;
TabPanel tabpanel = (TabPanel) ((WebFormComponent) comp).getFormElement().getPersistIfAvailable();
if (tabpanel.getTabOrientation() == TabPanel.SPLIT_HORIZONTAL || tabpanel.getTabOrientation() == TabPanel.SPLIT_VERTICAL) {
for (Object element : tabsList) {
Map<String, Object> tab = (Map<String, Object>) element;
if (tab != null) {
String relationName = tab.get("relationName") != null ? tab.get("relationName").toString() : null;
Object tabForm = tab.get("containsFormId");
if (tabForm != null) {
getFormUI().getDataAdapterList().addVisibleChildForm(getApplication().getFormManager().getForm(tabForm.toString()), relationName, true);
}
}
}
} else {
Map<String, Object> visibleTab = null;
if (tabIndex instanceof Number && tabsList.size() > 0 && ((Number) tabIndex).intValue() <= tabsList.size()) {
int index = ((Number) tabIndex).intValue() - 1;
if (index < 0) {
index = 0;
}
visibleTab = (Map<String, Object>) (tabsList.get(index));
} else if (tabIndex instanceof String || tabIndex instanceof CharSequence) {
for (Object element : tabsList) {
Map<String, Object> tab = (Map<String, Object>) element;
if (Utils.equalObjects(tabIndex, tab.get("name"))) {
visibleTab = tab;
break;
}
}
}
if (visibleTab != null) {
String relationName = visibleTab.get("relationName") != null ? visibleTab.get("relationName").toString() : null;
Object tabForm = visibleTab.get("containsFormId");
if (tabForm != null) {
getFormUI().getDataAdapterList().addVisibleChildForm(getApplication().getFormManager().getForm(tabForm.toString()), relationName, true);
}
}
}
}
}
}
}
// TODO should notifyVisibleSuccess be altered here? See WebFormUI/WebFormComponent notifyVisible calls.
if (notifyVisibleSuccess)
notifyVisibleOnChildren(visible, invokeLaterRunnables);
return notifyVisibleSuccess;
}
use of org.sablo.specification.WebObjectFunctionDefinition in project servoy-client by Servoy.
the class DataAdapterList method pushChanges.
public void pushChanges(WebFormComponent webComponent, String beanProperty, Object value, String foundsetLinkedRowID) {
// TODO should this all (svy-apply/push) move to DataProviderType client/server side implementation instead of these specialized calls, instanceof checks and string parsing (see getProperty or getPropertyDescription)?
String dataProviderID = getDataProviderID(webComponent, beanProperty);
if (dataProviderID == null) {
Debug.log("apply called on a property that is not bound to a dataprovider: " + beanProperty + ", value: " + value + " of component: " + webComponent);
return;
}
Object newValue = value;
// Check security
webComponent.checkPropertyProtection(beanProperty);
IRecordInternal editingRecord = record;
if (newValue instanceof FoundsetLinkedTypeSabloValue) {
if (foundsetLinkedRowID != null) {
// find the row of the foundset that changed; we can't use client's index (as server-side indexes might have changed meanwhile on server); so we are doing it based on client sent rowID
editingRecord = getFoundsetLinkedRecord((FoundsetLinkedTypeSabloValue<?, ?>) newValue, foundsetLinkedRowID);
if (editingRecord == null) {
Debug.error("Error pushing data from client to server for foundset linked DP (cannot find record): dp=" + newValue + ", rowID=" + foundsetLinkedRowID);
return;
}
}
// hmm, this is strange - usually we should always get rowID, even if foundset linked is actually set by developer to a global or form variable - even though there rowID is not actually needed; just treat this as if it is not record linked
newValue = ((FoundsetLinkedTypeSabloValue) newValue).getWrappedValue();
}
if (newValue instanceof DataproviderTypeSabloValue)
newValue = ((DataproviderTypeSabloValue) newValue).getValue();
if (editingRecord == null || editingRecord.startEditing() || editingRecord.getParentFoundSet().getColumnIndex(dataProviderID) == -1) {
Object v;
// will update property with "image_data", property_filename with "pic.jpg" and property_mimetype with "image/jpeg"
if (newValue instanceof HashMap) {
// defining value
v = ((HashMap<?, ?>) newValue).get("");
Iterator<Entry<?, ?>> newValueIte = ((HashMap) newValue).entrySet().iterator();
while (newValueIte.hasNext()) {
Entry<?, ?> e = newValueIte.next();
if (!"".equals(e.getKey())) {
try {
com.servoy.j2db.dataprocessing.DataAdapterList.setValueObject(editingRecord, formController.getFormScope(), dataProviderID + e.getKey(), e.getValue());
} catch (IllegalArgumentException ex) {
Debug.trace(ex);
getApplication().handleException(null, new ApplicationException(ServoyException.INVALID_INPUT, ex));
}
}
}
} else {
v = newValue;
}
Object oldValue = null;
Exception setValueException = null;
try {
oldValue = com.servoy.j2db.dataprocessing.DataAdapterList.setValueObject(editingRecord, formController.getFormScope(), dataProviderID, v);
if (value instanceof DataproviderTypeSabloValue)
((DataproviderTypeSabloValue) value).checkValueForChanges(editingRecord);
} catch (IllegalArgumentException e) {
Debug.trace(e);
getApplication().handleException(null, new ApplicationException(ServoyException.INVALID_INPUT, e));
setValueException = e;
webComponent.setInvalidState(true);
}
DataproviderConfig dataproviderConfig = getDataproviderConfig(webComponent, beanProperty);
String onDataChange = dataproviderConfig.getOnDataChange();
if (onDataChange != null) {
JSONObject event = EventExecutor.createEvent(onDataChange, editingRecord.getParentFoundSet().getSelectedIndex());
event.put("data", createDataproviderInfo(editingRecord, formController.getFormScope(), dataProviderID));
Object returnValue = null;
Exception exception = null;
String onDataChangeCallback = null;
if (!Utils.equalObjects(oldValue, v) && setValueException == null && webComponent.hasEvent(onDataChange)) {
// $NON-NLS-1$ //$NON-NLS-2$
getApplication().getWebsocketSession().getClientService("$sabloLoadingIndicator").executeAsyncNowServiceCall("showLoading", null);
try {
returnValue = webComponent.executeEvent(onDataChange, new Object[] { oldValue, v, event });
} catch (Exception e) {
Debug.error("Error during onDataChange webComponent=" + webComponent, e);
exception = e;
} finally {
// $NON-NLS-1$ //$NON-NLS-2$
getApplication().getWebsocketSession().getClientService("$sabloLoadingIndicator").executeAsyncNowServiceCall("hideLoading", null);
}
onDataChangeCallback = dataproviderConfig.getOnDataChangeCallback();
} else if (setValueException != null) {
returnValue = setValueException.getMessage();
exception = setValueException;
onDataChangeCallback = dataproviderConfig.getOnDataChangeCallback();
} else if (webComponent.isInvalidState() && exception == null) {
onDataChangeCallback = dataproviderConfig.getOnDataChangeCallback();
webComponent.setInvalidState(false);
}
if (onDataChangeCallback != null) {
WebObjectFunctionDefinition call = createWebObjectFunction(onDataChangeCallback);
webComponent.invokeApi(call, new Object[] { event, returnValue, exception == null ? null : exception.getMessage() });
}
}
}
}
Aggregations