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());
}
}
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;
}
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);
}
}
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());
}
}
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);
}
}
Aggregations