use of com.servoy.j2db.ApplicationException in project servoy-client by Servoy.
the class JSFoundSetUpdater method js_performUpdate.
/**
* Do the actual update in the database, returns true if successful. It will first try to save all editing records (from all foundsets), if cannot save will return false before doing the update.
* There are 3 types of possible use with the foundset updater
* 1) update entire foundset by a single sql statement; that is not possible when the table of the foundset has tracking enabled then it will loop over the whole foundset.
* When a single sql statement is done, modification columns will not be updated and associated Table Events won't be triggered, because it does the update directly in the database, without getting the records.
* NOTE: this mode will refresh all foundsets based on same datasource
* 2) update part of foundset, for example the first 4 row (starts with selected row)
* 3) safely loop through foundset (starts with selected row)
*
* after the perform update call there are no records in edit mode, that where not already in edit mode, because all of them are saved directly to the database,
* or in mode 1 the records are not touched at all and the database is updated directly.
*
* @sample
* //1) update entire foundset
* var fsUpdater = databaseManager.getFoundSetUpdater(foundset)
* fsUpdater.setColumn('customer_type',1)
* fsUpdater.setColumn('my_flag',0)
* fsUpdater.performUpdate()
*
* //2) update part of foundset, for example the first 4 row (starts with selected row)
* var fsUpdater = databaseManager.getFoundSetUpdater(foundset)
* fsUpdater.setColumn('customer_type',new Array(1,2,3,4))
* fsUpdater.setColumn('my_flag',new Array(1,0,1,0))
* fsUpdater.performUpdate()
*
* //3) safely loop through foundset (starts with selected row)
* controller.setSelectedIndex(1)
* var count = 0
* var fsUpdater = databaseManager.getFoundSetUpdater(foundset)
* while(fsUpdater.next())
* {
* fsUpdater.setColumn('my_flag',count++)
* }
*
* @return true if succeeded, false if failed.
*/
public boolean js_performUpdate() throws ServoyException {
if (list.size() == 0 || foundset.getTable() == null) {
return false;
}
if (!foundset.hasAccess(IRepository.UPDATE)) {
throw new ApplicationException(ServoyException.NO_MODIFY_ACCESS, new Object[] { foundset.getTable().getName() });
}
// first stop all edits, 'force' stop the edit by saying that it is a javascript stop
if (application.getFoundSetManager().getEditRecordList().stopEditing(true) != ISaveConstants.STOPPED)
return false;
try {
QuerySelect sqlParts;
IDataSet currentPKs;
synchronized (foundset.getPksAndRecords()) {
sqlParts = foundset.getPksAndRecords().getQuerySelectForReading();
currentPKs = foundset.getPksAndRecords().getPks();
}
FoundSetManager fsm = (FoundSetManager) application.getFoundSetManager();
if (rowsToUpdate == -1 && !foundset.hasAccess(IRepository.TRACKING) && sqlParts.getJoins() == null && // does not have join to other table
!fsm.hasTableFiltersWithJoins(foundset.getTable().getServerName(), sqlParts)) {
// all rows at once, via sql
Table table = (Table) foundset.getTable();
SQLSheet sheet = foundset.getSQLSheet();
QueryUpdate sqlUpdate = new QueryUpdate(sqlParts.getTable());
for (Pair<String, Object> p : list) {
String name = p.getLeft();
Object val = p.getRight();
int columnIndex = sheet.getColumnIndex(name);
VariableInfo variableInfo = sheet.getCalculationOrColumnVariableInfo(name, columnIndex);
if (// do not convert null to 0 incase of numbers, this means the calcs the value whould change each time //$NON-NLS-1$
val != null && !("".equals(val) && Column.mapToDefaultType(variableInfo.type) == IColumnTypes.TEXT)) {
val = sheet.convertObjectToValue(name, val, foundset.getFoundSetManager().getColumnConverterManager(), foundset.getFoundSetManager().getColumnValidatorManager(), null);
}
Column c = table.getColumn(name);
if (val == null) {
val = ValueFactory.createNullValue(c.getType());
}
sqlUpdate.addValue(c.queryColumn(sqlParts.getTable()), val);
}
sqlUpdate.setCondition(sqlParts.getWhereClone());
IDataSet pks;
boolean allFoundsetRecordsLoaded = currentPKs != null && currentPKs.getRowCount() <= fsm.pkChunkSize && !currentPKs.hadMoreRows();
if (allFoundsetRecordsLoaded) {
pks = currentPKs;
} else {
pks = new BufferedDataSet();
pks.addRow(new Object[] { ValueFactory.createTableFlushValue() });
}
String transaction_id = fsm.getTransactionID(foundset.getSQLSheet());
try {
SQLStatement statement = new SQLStatement(ISQLActionTypes.UPDATE_ACTION, table.getServerName(), table.getName(), pks, transaction_id, sqlUpdate, fsm.getTableFilterParams(table.getServerName(), sqlUpdate));
if (allFoundsetRecordsLoaded) {
statement.setExpectedUpdateCount(pks.getRowCount());
}
Object[] results = fsm.getDataServer().performUpdates(fsm.getApplication().getClientID(), new ISQLStatement[] { statement });
for (int i = 0; results != null && i < results.length; i++) {
if (results[i] instanceof ServoyException) {
if (((ServoyException) results[i]).getErrorCode() == ServoyException.UNEXPECTED_UPDATE_COUNT) {
performLoopUpdate();
clear();
return true;
}
fsm.flushCachedDatabaseData(fsm.getDataSource(table));
throw (ServoyException) results[i];
}
}
fsm.flushCachedDatabaseData(fsm.getDataSource(table));
clear();
return true;
} catch (ApplicationException aex) {
if (allFoundsetRecordsLoaded || aex.getErrorCode() != ServoyException.RECORD_LOCKED) {
throw aex;
}
// a record was locked by another client, try per-record
Debug.log("foundsetUpdater could not update all records in 1 statement (a record may be locked), trying per-record");
}
}
performLoopUpdate();
} catch (Exception ex) {
// $NON-NLS-1$
application.handleException(// $NON-NLS-1$
application.getI18NMessage("servoy.foundsetupdater.updateFailed"), new ApplicationException(ServoyException.SAVE_FAILED, ex));
return false;
}
clear();
return true;
}
use of com.servoy.j2db.ApplicationException in project servoy-client by Servoy.
the class Record method put.
public void put(String name, Scriptable start, final Object value) {
try {
// $NON-NLS-1$ //$NON-NLS-2$
if ("foundset".equals(name) || "exception".equals(name))
return;
// dont allow to set
if (jsFunctions.containsKey(name))
return;
Object realValue = value;
if (realValue instanceof IDelegate<?>) {
realValue = ((IDelegate<?>) realValue).getDelegate();
if (realValue instanceof IDataSet) {
IDataSet set = (IDataSet) realValue;
StringBuilder sb = new StringBuilder();
sb.append('\n');
for (int i = 0; i < set.getRowCount(); i++) {
sb.append(set.getRow(i)[0]);
sb.append('\n');
}
realValue = sb.toString();
}
} else if (realValue instanceof FoundSet) {
StringBuilder sb = new StringBuilder();
sb.append('\n');
FoundSet fs = (FoundSet) realValue;
for (int i = 0; i < fs.getSize(); i++) {
IRecordInternal record = fs.getRecord(i);
sb.append(record.getPKHashKey());
sb.append('\n');
}
realValue = sb.toString();
} else {
Object tmp = realValue;
while (tmp instanceof Wrapper) {
tmp = ((Wrapper) tmp).unwrap();
if (tmp == realValue) {
break;
}
}
realValue = tmp;
}
boolean dbColumn = parent.getSQLSheet().getColumnIndex(name) != -1;
if (// make sure any js change is noted
!dbColumn || startEditing()) {
if (realValue instanceof Date) {
// make copy so then when it is further used in js it won't change this one.
// make copy so changes are seen (date is mutable and whould bypass equals)
realValue = new Date(((Date) realValue).getTime());
}
Object oldVal = setValue(name, realValue);
if (// did change?
oldVal != realValue) {
fireJSModificationEvent(name, realValue);
}
} else {
((FoundSetManager) parent.getFoundSetManager()).getApplication().handleException(null, new ApplicationException(ServoyException.RECORD_LOCKED));
}
} catch (RuntimeException e) {
throw new WrappedException(e);
}
}
use of com.servoy.j2db.ApplicationException in project servoy-client by Servoy.
the class NGClientEndpoint method handleException.
@Override
protected void handleException(final Exception e, final IWebsocketSession session) {
if (e instanceof ApplicationException) {
final ApplicationException ae = (ApplicationException) e;
// if the current window has no endpoint then quickly set it to this instance.
if (CurrentWindow.exists() && !CurrentWindow.get().hasEndpoint())
CurrentWindow.get().setEndpoint(this);
CurrentWindow.runForWindow(new NGClientWebsocketSessionWindows((INGClientWebsocketSession) session), new Runnable() {
@Override
public void run() {
if (ae.getErrorCode() == ServoyException.NO_LICENSE) {
session.getClientService("$sessionService").executeAsyncServiceCall("setNoLicense", new Object[] { getLicenseAndMaintenanceDetail() });
} else if (ae.getErrorCode() == ServoyException.MAINTENANCE_MODE) {
session.getClientService("$sessionService").executeAsyncServiceCall("setMaintenanceMode", new Object[] { getLicenseAndMaintenanceDetail() });
}
}
});
}
try {
((NGClient) ((INGClientWebsocketSession) session).getClient()).shutDown(true);
} catch (Exception e1) {
Debug.error("Error calling shutdown on client that had an exception when starting up: " + e.getMessage(), e1);
}
}
use of com.servoy.j2db.ApplicationException 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() });
}
}
}
}
use of com.servoy.j2db.ApplicationException in project servoy-client by Servoy.
the class JSApplication method js_showFormInWindow.
/**
* Show the specified form in a window. (NOTE: x, y, width, height are initial bounds - applied only the fist time a window is shown)
*
* NOTE:
* Forms in windows cannot be modal. They are more independent then dialogs, even non-modal ones. For example in SC, a non-modal dialog will always
* be shown on top of the parent window and it will not have a separate entry in the OS window manager (for example Windows taskbar).
*
* NOTE:
* x, y, width and height coordinates are only applied the first time the specified window is shown.
* Use APP_UI_PROPERTY.FULL_SCREEN for these values when the window should be full-screen.
*
* @deprecated As of release 6.0, dialogs/windows API has been rewritten (based in JSWindow objects)
*
* @sample
* //Show the specified form in a window, on default initial location and size
* //application.showFormInWindow(forms.contacts);
* //Show the specified form in a window with a specified name, on default initial location and size
* //application.showFormInWindow(forms.contacts,'contactsWindow');
* //Show the specified form in a window, at a specified initial location and size with custom title, not resizable but with text toolbar
* application.showFormInWindow(forms.contacts,100,80,500,300,'my own window title',false,true,'mywindow');
*
* @param form The form to be shown in the dialog.
* @param x optional The "x" coordinate of the dialog.
* @param y optional The "y" coordinate of the dialog.
* @param width optional The width of the dialog.
* @param height optional The height of the dialog.
* @param dialogTitle optional The title of the dialog.
* @param resizable optional <em>true</em> if the dialog size should be modifiable; <em>false</em> if not.
* @param showTextToolbar optional <em>true</em> to add a text toolbar; <em>false</em> to not add a text toolbar.
* @param windowName optional The name of the window; defaults to "dialog" if nothing is specified. Window and dialog names share the same namespace.
*/
@Deprecated
public void js_showFormInWindow(Object[] args) throws ServoyException {
if (args != null && args.length >= 1) {
Object form = args[0];
int x = -1;
int y = -1;
int w = 0;
int h = 0;
String title = null;
boolean resizeble = true;
boolean showTextToolbar = false;
String windowName = null;
// special short cut, args: 'form,name'
if (args.length >= 2 && args[1] instanceof String) {
windowName = (String) args[1];
} else {
if (args.length >= 2 && args[1] instanceof Number)
x = ((Number) args[1]).intValue();
if (args.length >= 3 && args[2] instanceof Number)
y = ((Number) args[2]).intValue();
if (args.length >= 4 && args[3] instanceof Number)
w = ((Number) args[3]).intValue();
if (args.length >= 5 && args[4] instanceof Number)
h = ((Number) args[4]).intValue();
if (args.length >= 6 && args[5] instanceof String)
title = args[5].toString();
if (args.length >= 7 && args[6] instanceof Boolean)
resizeble = ((Boolean) args[6]).booleanValue();
if (args.length >= 8 && args[7] instanceof Boolean)
showTextToolbar = ((Boolean) args[7]).booleanValue();
if (args.length >= 9 && args[8] instanceof String)
windowName = (String) args[8];
}
windowName = replaceFailingCharacters(windowName);
String formName = null;
if (form instanceof BasicFormController) {
formName = ((BasicFormController) form).getName();
} else if (form instanceof FormScope) {
formName = ((FormScope) form).getFormController().getName();
} else if (form instanceof BasicFormController.JSForm) {
formName = ((FormController.JSForm) form).getFormPanel().getName();
} else if (form instanceof String) {
formName = (String) form;
}
if (formName != null) {
Form frm = application.getFlattenedSolution().getForm(formName);
IBasicFormManager fm = application.getFormManager();
if (frm == null && fm.isPossibleForm(formName))
frm = fm.getPossibleForm(formName);
if (!application.getFlattenedSolution().formCanBeInstantiated(frm)) {
// abstract form
throw new ApplicationException(ServoyException.ABSTRACT_FORM);
}
Rectangle bounds = new Rectangle(x, y, w, h);
fm.showFormInFrame(formName, bounds, title, resizeble, showTextToolbar, windowName);
}
}
}
Aggregations