use of org.eclipse.scout.rt.platform.exception.ProcessingException in project scout.rt by eclipse.
the class FormDataStatementBuilder method createAttributePart.
/**
* adding an attribute as an entity contribution
* <p>
* Evaluates the tags in the attribute statement and creates an {@link EntityContribution} based on it.
*
* @param stm
* may contain attribute, fromPart and wherePart tags
*/
@SuppressWarnings({ "bsiRulesDefinition:htmlInString", "squid:S00107" })
public EntityContribution createAttributePart(AttributeStrategy attributeStrategy, Integer aggregationType, String stm, int operation, List<String> bindNames, List<Object> bindValues, final boolean plainBind, Map<String, String> parentAliasMap) {
if (stm == null) {
return new EntityContribution();
}
// convenience: automatically wrap attribute in attribute tags
if (stm.indexOf("<attribute>") < 0) {
stm = "<attribute>" + stm + "</attribute>";
}
// convenience: automatically add missing alias on plain attributes, but only if the parent entity has at most 1 alias mapping
Matcher m = PLAIN_ATTRIBUTE_PATTERN.matcher(stm);
if (m.find()) {
if (parentAliasMap.size() == 0) {
// nop
} else if (parentAliasMap.size() == 1) {
stm = m.replaceAll("$1@parent." + parentAliasMap.keySet().iterator().next() + "@.$2$3");
} else {
throw new ProcessingException("composer attribute " + stm + " uses no @...@ alias prefix, but parent has more than 1 alias: " + parentAliasMap);
}
}
boolean isAg = (aggregationType != null && aggregationType != AGGREGATION_NONE);
EntityContribution contrib = new EntityContribution();
// special handling of NOT: wrap NOT around complete constraint text and not only in attribute operator
int positiveOperation;
boolean negation;
switch(operation) {
case OPERATOR_DATE_IS_NOT_TODAY:
{
positiveOperation = OPERATOR_DATE_IS_TODAY;
negation = true;
break;
}
case OPERATOR_DATE_NEQ:
{
positiveOperation = OPERATOR_DATE_EQ;
negation = true;
break;
}
case OPERATOR_DATE_TIME_IS_NOT_NOW:
{
positiveOperation = OPERATOR_DATE_TIME_IS_NOW;
negation = true;
break;
}
case OPERATOR_DATE_TIME_NEQ:
{
positiveOperation = OPERATOR_DATE_TIME_EQ;
negation = true;
break;
}
case OPERATOR_NEQ:
{
positiveOperation = OPERATOR_EQ;
negation = true;
break;
}
case OPERATOR_NOT_CONTAINS:
{
positiveOperation = OPERATOR_CONTAINS;
negation = true;
break;
}
case OPERATOR_NOT_ENDS_WITH:
{
positiveOperation = OPERATOR_ENDS_WITH;
negation = true;
break;
}
case OPERATOR_NOT_IN:
{
positiveOperation = OPERATOR_IN;
negation = true;
break;
}
case OPERATOR_NOT_NULL:
{
positiveOperation = OPERATOR_NULL;
negation = true;
break;
}
case OPERATOR_NOT_STARTS_WITH:
{
positiveOperation = OPERATOR_STARTS_WITH;
negation = true;
break;
}
case OPERATOR_NUMBER_NOT_NULL:
{
positiveOperation = OPERATOR_NUMBER_NULL;
negation = true;
break;
}
case OPERATOR_TIME_IS_NOT_NOW:
{
positiveOperation = OPERATOR_TIME_IS_NOW;
negation = true;
break;
}
default:
{
positiveOperation = operation;
negation = false;
}
}
//
String fromPart = StringUtility.getTag(stm, "fromPart");
stm = StringUtility.removeTag(stm, "fromPart").trim();
String wherePart = StringUtility.getTag(stm, "wherePart");
if (wherePart == null) {
String tmp = StringUtility.removeTag(stm, "attribute").trim();
if (tmp.length() > 0) {
wherePart = stm;
stm = "";
}
}
stm = StringUtility.removeTag(stm, "wherePart").trim();
String attPart = StringUtility.getTag(stm, "attribute");
stm = StringUtility.removeTag(stm, "attribute").trim();
if (stm.length() > 0) {
LOG.warn("attribute part is not well-formed; contains wherePart tag and also other sql text: {}", stm);
}
// from
if (fromPart != null) {
// resolve aliases in from
// mis-using 'contrib' as a "node" because real node is not accessible
m_aliasMapper.addMissingNodeEntitiesFrom(contrib, fromPart);
Map<String, String> aliasMap = m_aliasMapper.getNodeAliases(contrib);
parentAliasMap.putAll(aliasMap);
fromPart = m_aliasMapper.replaceMarkersByAliases(fromPart, parentAliasMap, parentAliasMap);
contrib.getFromParts().add(fromPart);
}
switch(attributeStrategy) {
// select ... where
case BuildQueryOfAttributeAndConstraintOfContext:
{
// select
if (attPart != null) {
String sql = createSqlPart(aggregationType, attPart, OPERATOR_NONE, bindNames, bindValues, plainBind, parentAliasMap);
if (sql != null) {
contrib.getSelectParts().add(sql);
if (!isAg) {
contrib.getGroupByParts().add(sql);
}
}
}
// where
if (wherePart != null) {
wherePart = StringUtility.replaceTags(wherePart, "attribute", "1=1").trim();
String sql = createSqlPart(wherePart, bindNames, bindValues, plainBind, parentAliasMap);
if (sql != null) {
contrib.getWhereParts().add(sql);
}
}
break;
}
// where / having
case BuildConstraintOfAttribute:
{
if (attPart != null) {
String sql = createSqlPart(aggregationType, attPart, positiveOperation, bindNames, bindValues, plainBind, parentAliasMap);
if (sql != null) {
if (negation) {
sql = "NOT(" + sql + ")";
}
if (isAg) {
contrib.getHavingParts().add(sql);
} else {
contrib.getWhereParts().add(sql);
}
}
}
break;
}
case BuildConstraintOfContext:
{
if (wherePart != null) {
wherePart = StringUtility.replaceTags(wherePart, "attribute", "1=1").trim();
String sql = createSqlPart(wherePart, bindNames, bindValues, plainBind, parentAliasMap);
if (sql != null) {
contrib.getWhereParts().add(sql);
}
}
break;
}
case BuildConstraintOfAttributeWithContext:
{
String whereAndAttPart = (wherePart != null ? wherePart : "") + (wherePart != null && attPart != null ? " AND " : "") + (attPart != null ? "<attribute>" + attPart + "</attribute>" : "");
if (whereAndAttPart.length() > 0) {
String sql = createSqlPart(aggregationType, whereAndAttPart, positiveOperation, bindNames, bindValues, plainBind, parentAliasMap);
if (sql != null) {
if (negation) {
sql = "NOT(" + sql + ")";
}
contrib.getWhereParts().add(sql);
}
}
break;
}
}
return contrib;
}
use of org.eclipse.scout.rt.platform.exception.ProcessingException in project scout.rt by eclipse.
the class AbstractSqlService method execCustomBindFunction.
/**
* Custom functions that can be used in sql statements as binds or sql style independent functions
* <p>
* Default functions are<br>
* ::level(permissionClass) --> int //to resolve a permissin level by executing a permission<br>
* ::level(permissionLevel) --> int //to resolve a permissin level by its id<br>
* ::code(codeClass or codeTypeClass) --> the ID of the code or code type<br>
* ::text(textId) --> the text in the user sessions language
* <p>
* Examples:<br>
* ::level(UpdatePersonPermission)<br>
* ::level(UpdatePersonPermission.LEVEL_OWN)<br>
* <br>
* ::code(CompanyAddressCodeType.MainAddressCode)<br>
* ::code(MainAddressCode)<br>
* <br>
* ::text(SalutationMr)
* <p>
*
* @return a plain object value or in case of a null value preferrably a {@link IHolder} of the correct value type
*/
@ConfigOperation
@Order(40)
protected Object execCustomBindFunction(String functionName, String[] args, Object[] bindBases) {
if ("level".equals(functionName)) {
if (args.length != 1) {
throw new IllegalArgumentException("expected 1 argument for function '" + functionName + "'");
}
String permissionClassName = args[0];
String levelField = null;
// eventually a level id?
int levelDot = permissionClassName.indexOf(".LEVEL_");
if (levelDot >= 0) {
levelField = permissionClassName.substring(levelDot + 1);
permissionClassName = permissionClassName.substring(0, levelDot);
}
Class permissionClass = loadBundleClassLenient(m_permissionNameToDescriptor, permissionClassName);
IAccessControlService accessControlService = BEANS.get(IAccessControlService.class);
Object ret = tryGetPermissionLevel(permissionClass, levelField, accessControlService);
return ret != null ? ret : new LongHolder();
} else if ("code".equals(functionName)) {
if (args.length != 1) {
throw new IllegalArgumentException("expected 1 argument for function '" + functionName + "'");
}
String codeClassName = args[0];
Class codeClass = loadBundleClassLenient(m_codeNameToDescriptor, codeClassName);
if (codeClass == null) {
throw new ProcessingException("Cannot find class for code '{}", new Object[] { args[0] });
}
try {
Object ret = codeClass.getField("ID").get(null);
return ret != null ? ret : new LongHolder();
} catch (Exception t) {
throw new ProcessingException("ID of code '{}'", new Object[] { args[0], t });
}
} else if ("text".equals(functionName)) {
if (args.length < 1) {
throw new IllegalArgumentException("expected at least 1 argument for function '" + functionName + "'");
}
String ret = TEXTS.get(args[0]);
return ret != null ? ret : new StringHolder();
} else {
throw new IllegalArgumentException("undefined function '" + functionName + "'");
}
}
use of org.eclipse.scout.rt.platform.exception.ProcessingException in project scout.rt by eclipse.
the class AbstractSqlService method commit.
@Override
public void commit() {
try {
getTransaction().commit();
ISqlStyle style = getSqlStyle();
if (style != null) {
style.commit();
}
} catch (SQLException e) {
throw new ProcessingException("Failed to commit", e);
}
}
use of org.eclipse.scout.rt.platform.exception.ProcessingException in project scout.rt by eclipse.
the class FunctionInput method produceSqlBindAndSetReplaceToken.
@Override
public SqlBind produceSqlBindAndSetReplaceToken(ISqlStyle sqlStyle) {
if (isBatch() || !m_valueSet) {
if (m_callerService instanceof AbstractSqlService) {
m_value = ((AbstractSqlService) m_callerService).callbackCustomBindFunction(m_target.getName(), m_target.getArgs(), m_bindBases);
} else {
throw new ProcessingException("don't know how to resolve custom bind function '" + m_target.getName() + "' on service " + m_callerService.getClass().getName());
}
m_valueSet = true;
}
Object value = null;
if (isBatch() && m_batchIndex >= 1) {
value = null;
} else {
value = m_value;
}
Class<?> nullType = null;
if (value instanceof IHolder<?>) {
IHolder h = (IHolder<?>) value;
value = h.getValue();
nullType = h.getHolderType();
}
//
if (m_target.isPlainToken()) {
m_target.setReplaceToken(m_target.getParsedToken());
return null;
} else if (m_target.isPlainValue()) {
m_target.setReplaceToken(sqlStyle.toPlainText(value));
return null;
} else if (m_target.isPlainSql()) {
m_target.setReplaceToken("" + value);
return null;
} else {
m_target.setReplaceToken("?");
return sqlStyle.buildBindFor(value, nullType);
}
}
use of org.eclipse.scout.rt.platform.exception.ProcessingException in project scout.rt by eclipse.
the class StatementProcessor method createOutput.
@SuppressWarnings("bsiRulesDefinition:htmlInString")
private IBindOutput createOutput(IToken bindToken, Object[] bindBases) {
if (bindToken instanceof ValueOutputToken) {
IBindOutput result = null;
ValueOutputToken valueOutputToken = (ValueOutputToken) bindToken;
String[] path = REGEX_DOT.split(valueOutputToken.getName());
for (int i = 0; i < bindBases.length; i++) {
IBindOutput out = createOutputRec(valueOutputToken, path, bindBases[i]);
if (out != null) {
if (isBindDuplicateCheckEnabled()) {
if (result == null) {
// first match found for the bind -> remember
result = out;
} else {
// second match found
onDuplicateBind(valueOutputToken);
return result;
}
} else {
// no duplicate check necessary: directly return the first match
return out;
}
}
}
if (result == null) {
throw new ProcessingException("Cannot find output for '{}' in bind base. When selecting into shared context variables make sure these variables are initialized using CONTEXT.set<i>PropertyName</i>(null)", valueOutputToken);
}
return result;
}
throw new ProcessingException("Cannot find output for {}", bindToken.getClass());
}
Aggregations