Search in sources :

Example 1 with TypedData

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);
}
Also used : PropertyDescription(org.sablo.specification.PropertyDescription) WebObjectSpecification(org.sablo.specification.WebObjectSpecification) TypedData(org.sablo.websocket.TypedData) HashMap(java.util.HashMap) PropertyDescriptionBuilder(org.sablo.specification.PropertyDescriptionBuilder) JSONObject(org.json.JSONObject) ServoyJSONObject(com.servoy.j2db.util.ServoyJSONObject) Dimension(java.awt.Dimension)

Example 2 with TypedData

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);
    }
}
Also used : TypedData(org.sablo.websocket.TypedData) IllegalChangeFromClientException(org.sablo.IllegalChangeFromClientException) IFoundSetInternal(com.servoy.j2db.dataprocessing.IFoundSetInternal) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) ParseException(java.text.ParseException) IllegalChangeFromClientException(org.sablo.IllegalChangeFromClientException) PropertyDescription(org.sablo.specification.PropertyDescription) IWebFormUI(com.servoy.j2db.server.ngclient.IWebFormUI) JSONObject(org.json.JSONObject) Iterator(java.util.Iterator) IDataAdapterList(com.servoy.j2db.server.ngclient.IDataAdapterList) JSONObject(org.json.JSONObject) ParseException(java.text.ParseException)

Example 3 with TypedData

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;
}
Also used : WebObjectSpecification(org.sablo.specification.WebObjectSpecification) TypedData(org.sablo.websocket.TypedData) JSONArray(org.json.JSONArray) RepositoryException(com.servoy.j2db.persistence.RepositoryException) WebObjectFunctionDefinition(org.sablo.specification.WebObjectFunctionDefinition) ServoyException(com.servoy.j2db.util.ServoyException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ApplicationException(com.servoy.j2db.ApplicationException) RemoteException(java.rmi.RemoteException) MalformedURLException(java.net.MalformedURLException) RepositoryException(com.servoy.j2db.persistence.RepositoryException) BaseWebObject(org.sablo.BaseWebObject) WebServiceScriptable(com.servoy.j2db.server.ngclient.scripting.WebServiceScriptable) JSONObject(org.json.JSONObject) PluginScope(com.servoy.j2db.scripting.PluginScope) BaseWebObject(org.sablo.BaseWebObject) JSONObject(org.json.JSONObject) ArrayList(java.util.ArrayList) List(java.util.List) BrowserConverterContext(org.sablo.specification.property.BrowserConverterContext)

Example 4 with TypedData

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;
}
Also used : TypedData(org.sablo.websocket.TypedData) FlattenedSolution(com.servoy.j2db.FlattenedSolution) JSONException(org.json.JSONException) JSONObject(org.json.JSONObject) FormElementContext(com.servoy.j2db.server.ngclient.FormElementContext)

Aggregations

JSONObject (org.json.JSONObject)4 TypedData (org.sablo.websocket.TypedData)4 JSONArray (org.json.JSONArray)2 JSONException (org.json.JSONException)2 PropertyDescription (org.sablo.specification.PropertyDescription)2 WebObjectSpecification (org.sablo.specification.WebObjectSpecification)2 ApplicationException (com.servoy.j2db.ApplicationException)1 FlattenedSolution (com.servoy.j2db.FlattenedSolution)1 IFoundSetInternal (com.servoy.j2db.dataprocessing.IFoundSetInternal)1 RepositoryException (com.servoy.j2db.persistence.RepositoryException)1 PluginScope (com.servoy.j2db.scripting.PluginScope)1 FormElementContext (com.servoy.j2db.server.ngclient.FormElementContext)1 IDataAdapterList (com.servoy.j2db.server.ngclient.IDataAdapterList)1 IWebFormUI (com.servoy.j2db.server.ngclient.IWebFormUI)1 WebServiceScriptable (com.servoy.j2db.server.ngclient.scripting.WebServiceScriptable)1 ServoyException (com.servoy.j2db.util.ServoyException)1 ServoyJSONObject (com.servoy.j2db.util.ServoyJSONObject)1 Dimension (java.awt.Dimension)1 IOException (java.io.IOException)1 MalformedURLException (java.net.MalformedURLException)1