Search in sources :

Example 16 with IFoundSetInternal

use of com.servoy.j2db.dataprocessing.IFoundSetInternal in project servoy-client by Servoy.

the class SpecialSplitPane method registerSelectionListeners.

private void registerSelectionListeners(IRecordInternal parentState, String relationName) {
    // $NON-NLS-1$
    String[] parts = relationName.split("\\.");
    IRecordInternal currentRecord = parentState;
    for (int i = 0; currentRecord != null && i < parts.length - 1; i++) {
        IFoundSetInternal fs = currentRecord.getRelatedFoundSet(parts[i]);
        if (fs instanceof ISwingFoundSet) {
            related.add((ISwingFoundSet) fs);
            ((ISwingFoundSet) fs).getSelectionModel().addListSelectionListener(this);
        }
        currentRecord = (fs == null) ? null : fs.getRecord(fs.getSelectedIndex());
    }
}
Also used : IRecordInternal(com.servoy.j2db.dataprocessing.IRecordInternal) IFoundSetInternal(com.servoy.j2db.dataprocessing.IFoundSetInternal) ISwingFoundSet(com.servoy.j2db.dataprocessing.ISwingFoundSet)

Example 17 with IFoundSetInternal

use of com.servoy.j2db.dataprocessing.IFoundSetInternal in project servoy-client by Servoy.

the class NGFoundSetManager method executeMethod.

@SuppressWarnings("nls")
@Override
public Object executeMethod(String methodName, JSONObject args) throws Exception {
    if ("getFoundSet".equals(methodName)) {
        IFoundSetInternal foundset = FoundsetReferencePropertyTypeOld.INSTANCE.fromJSON(args, null, null, null, null);
        String sort = args.optString("sort");
        if (!"".equals(sort)) {
            foundset.setSort(sort);
        }
        FoundsetTypeSabloValue value = getFoundsetTypeSabloValue(foundset, args.optJSONObject("dataproviders"));
        ChangeAwareList<ChangeAwareMap<String, Object>, Object> foundsets = (ChangeAwareList<ChangeAwareMap<String, Object>, Object>) ((NGClient) getApplication()).getWebsocketSession().getClientService("foundset_manager").getProperty("foundsets");
        if (foundsets == null) {
            foundsets = new ChangeAwareList<ChangeAwareMap<String, Object>, Object>(new ArrayList<ChangeAwareMap<String, Object>>());
            ((NGClient) getApplication()).getWebsocketSession().getClientService("foundset_manager").setProperty("foundsets", foundsets);
        }
        boolean newFoundsetInfo = true;
        for (ChangeAwareMap<String, Object> foundsetInfoMap : foundsets) {
            if (foundsetInfoMap.containsValue(value)) {
                newFoundsetInfo = false;
                break;
            }
        }
        if (newFoundsetInfo) {
            HashMap<String, Object> foundsetinfoMap = new HashMap<String, Object>();
            foundsetinfoMap.put("foundset", value);
            foundsetinfoMap.put("foundsethash", args.optString("foundsethash"));
            String childrelation = args.optString("childrelation");
            if (childrelation != null) {
                JSONObject childrelationinfo = new JSONObject();
                childrelationinfo.put("name", childrelation);
                for (int i = 0; i < foundset.getSize(); i++) {
                    IRecordInternal record = foundset.getRecord(i);
                    Object o = record.getValue(childrelation);
                    if (o instanceof IFoundSetInternal) {
                        childrelationinfo.put(record.getPKHashKey() + "_" + record.getParentFoundSet().getRecordIndex(record), ((IFoundSetInternal) o).getSize());
                    }
                }
                foundsetinfoMap.put("childrelationinfo", childrelationinfo);
            }
            CustomJSONObjectType dummyCustomObjectTypeForChildRelationInfo = (CustomJSONObjectType) TypesRegistry.createNewType(CustomJSONObjectType.TYPE_NAME, "svy__dummyCustomObjectTypeForDeprecatedFMServiceChildRelationInfo");
            PropertyDescription dummyPD = new PropertyDescriptionBuilder().withType(dummyCustomObjectTypeForChildRelationInfo).build();
            dummyCustomObjectTypeForChildRelationInfo.setCustomJSONDefinition(dummyPD);
            foundsets.add(new ChangeAwareMap(foundsetinfoMap, null, dummyPD));
        }
    } else if ("getRelatedFoundSetHash".equals(methodName)) {
        IFoundSetInternal foundset = FoundsetReferencePropertyTypeOld.INSTANCE.fromJSON(args, null, null, null, null);
        String rowid = args.optString("rowid");
        String relation = args.optString("relation");
        Pair<String, Integer> splitHashAndIndex = FoundsetTypeSabloValue.splitPKHashAndIndex(rowid);
        int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
        if (recordIndex != -1) {
            IRecordInternal record = foundset.getRecord(recordIndex);
            Object o = record.getValue(relation);
            if (o instanceof IFoundSetInternal) {
                IFoundSetInternal relatedFoundset = (IFoundSetInternal) o;
                PropertyDescription foundsetRefProperty = new PropertyDescriptionBuilder().withType(FoundsetReferencePropertyTypeOld.INSTANCE).build();
                return new TypedData<IFoundSetInternal>(relatedFoundset, foundsetRefProperty);
            }
        }
    } else if ("updateFoundSetRow".equals(methodName)) {
        IFoundSetInternal foundset = FoundsetReferencePropertyTypeOld.INSTANCE.fromJSON(args, null, null, null, null);
        String rowid = args.optString("rowid");
        String dataproviderid = args.optString("dataproviderid");
        Object value = args.get("value");
        Pair<String, Integer> splitHashAndIndex = FoundsetTypeSabloValue.splitPKHashAndIndex(rowid);
        int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
        if (recordIndex != -1) {
            IRecordInternal record = foundset.getRecord(recordIndex);
            if (record.startEditing()) {
                record.setValue(dataproviderid, value);
                return Boolean.TRUE;
            }
        }
    } else if ("removeFoundSetFromCache".equals(methodName)) {
        IFoundSetInternal foundset = FoundsetReferencePropertyTypeOld.INSTANCE.fromJSON(args, null, null, null, null);
        removeFoundSetTypeSabloValue(foundset);
    } else if ("removeFoundSetsFromCache".equals(methodName)) {
        ChangeAwareList<ChangeAwareMap<String, Object>, Object> foundsets = (ChangeAwareList<ChangeAwareMap<String, Object>, Object>) ((NGClient) getApplication()).getWebsocketSession().getClientService("foundset_manager").getProperty("foundsets");
        if (foundsets != null) {
            foundsets.clear();
        }
        foundsetTypeSabloValueMap.clear();
    }
    return null;
}
Also used : IRecordInternal(com.servoy.j2db.dataprocessing.IRecordInternal) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) IFoundSetInternal(com.servoy.j2db.dataprocessing.IFoundSetInternal) PropertyDescriptionBuilder(org.sablo.specification.PropertyDescriptionBuilder) ArrayList(java.util.ArrayList) ChangeAwareList(org.sablo.specification.property.ChangeAwareList) PropertyDescription(org.sablo.specification.PropertyDescription) FoundsetTypeSabloValue(com.servoy.j2db.server.ngclient.property.FoundsetTypeSabloValue) JSONObject(org.json.JSONObject) CustomJSONObjectType(org.sablo.specification.property.CustomJSONObjectType) ChangeAwareMap(org.sablo.specification.property.ChangeAwareMap) JSONObject(org.json.JSONObject) Pair(com.servoy.j2db.util.Pair)

Example 18 with IFoundSetInternal

use of com.servoy.j2db.dataprocessing.IFoundSetInternal 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 19 with IFoundSetInternal

use of com.servoy.j2db.dataprocessing.IFoundSetInternal in project servoy-client by Servoy.

the class ComponentTypeSabloValue method updatePropertyValueForRecord.

protected void updatePropertyValueForRecord(FoundsetTypeSabloValue foundsetPropertyValue, String rowIDValue, String propertyName, Object value) {
    IFoundSetInternal foundset = foundsetPropertyValue.getFoundset();
    Pair<String, Integer> splitHashAndIndex = FoundsetTypeSabloValue.splitPKHashAndIndex(rowIDValue);
    if (foundset != null) {
        int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
        if (recordIndex != -1) {
            // ok we found the record; check that it is still available in the viewport of this foundset linked component (as it might have been excluded from viewport prior to this)
            FoundsetTypeViewport vp = foundsetPropertyValue.getViewPort();
            if (vp.getStartIndex() <= recordIndex && recordIndex < (vp.getStartIndex() + vp.getSize())) {
                foundsetPropertyValue.getDataAdapterList().setRecordQuietly(foundset.getRecord(recordIndex));
                try {
                    childComponent.putBrowserProperty(propertyName, value);
                } catch (JSONException e) {
                    Debug.error("Setting value for record dependent property '" + propertyName + "' in foundset linked component to value: " + value + " failed.", e);
                }
            } else {
                // normally when this happens it is a strange sequence of requests from the client side component (updates are sent for components that are no longer inside the used viewport)
                // for example a list form component that uses a form component that contains an extra table (related foundset)
                // had a bad behavior that, after it received 50 records initially, it would only need 9 and would request loadLessRecords -41/41 twice on the main foundset (=> 0 size viewport server side)
                // but at the same time the extra-table that corresponds to the first record had many related rows and it also sent update from browser to loadLessRecords then initially...
                // so the list form components viewport was size 0 on server already but an update came for a child component - a record that does exist, but is no longer in viewport;
                // and that resulted in a valid loadLess on the extra table but which was marked as handled correctly (handleID) but it was never sent back to client as it no longer existed on client
                // and when list form component corrected it's viewport again to be 0-9, the nested foundset property type of the extra table still had that "handledID" set
                // so basically it sent a handledID to client for a previous value "undefined" (as viewport was 0) => exception on client
                // 
                // I think we can safely ignore these type of requests - as they are for obsolete records
                Debug.debug("Cannot set foundset linked record dependent component property for (" + rowIDValue + ") property '" + propertyName + "' to value '" + value + "' of component: " + childComponent + ". Record found, but out of current viewport.");
            }
        } else {
            Debug.error("Cannot set foundset linked record dependent component property for (" + rowIDValue + ") property '" + propertyName + "' to value '" + value + "' of component: " + childComponent + ". Record not found.", new RuntimeException());
        }
    } else {
        Debug.error("Cannot set foundset linked record dependent component property for (" + rowIDValue + ") property '" + propertyName + "' to value '" + value + "' of component: " + childComponent + ". Foundset is null.", new RuntimeException());
    }
}
Also used : IFoundSetInternal(com.servoy.j2db.dataprocessing.IFoundSetInternal) JSONException(org.json.JSONException)

Example 20 with IFoundSetInternal

use of com.servoy.j2db.dataprocessing.IFoundSetInternal in project servoy-client by Servoy.

the class FoundsetDataAdapterList method resetDALToSelectedIndexQuietly.

public void resetDALToSelectedIndexQuietly() {
    // see https://support.servoy.com/browse/SVY-11537; DataproviderTypeSabloValues do listen to related data but only on the row in the foundset DAL
    IFoundSetInternal foundset;
    if (getRecord() != null)
        foundset = getRecord().getParentFoundSet();
    else
        foundset = null;
    if (foundset != null && foundset.getSize() > 0) {
        IRecord selectedRecord = foundset.getRecord(foundset.getSelectedIndex());
        setRecordQuietly(selectedRecord, true);
    } else {
        // to make sure DAL is not listening to records that are no longer in the foundset
        setRecordQuietly(null, true);
    }
}
Also used : IFoundSetInternal(com.servoy.j2db.dataprocessing.IFoundSetInternal) IRecord(com.servoy.j2db.dataprocessing.IRecord)

Aggregations

IFoundSetInternal (com.servoy.j2db.dataprocessing.IFoundSetInternal)55 IRecordInternal (com.servoy.j2db.dataprocessing.IRecordInternal)26 Point (java.awt.Point)13 FormController (com.servoy.j2db.FormController)12 ISwingFoundSet (com.servoy.j2db.dataprocessing.ISwingFoundSet)11 ServoyException (com.servoy.j2db.util.ServoyException)8 ArrayList (java.util.ArrayList)8 IApplication (com.servoy.j2db.IApplication)6 FoundSet (com.servoy.j2db.dataprocessing.FoundSet)6 EventObject (java.util.EventObject)6 ITagResolver (com.servoy.base.util.ITagResolver)5 FindState (com.servoy.j2db.dataprocessing.FindState)5 IDisplayData (com.servoy.j2db.dataprocessing.IDisplayData)5 PrototypeState (com.servoy.j2db.dataprocessing.PrototypeState)5 RepositoryException (com.servoy.j2db.persistence.RepositoryException)5 JSONObject (org.json.JSONObject)5 FormManager (com.servoy.j2db.FormManager)4 SortColumn (com.servoy.j2db.dataprocessing.SortColumn)4 IScriptableProvider (com.servoy.j2db.scripting.IScriptableProvider)4 Color (java.awt.Color)4