private String substituteContextParameters(String currentWhereClause) { // This method will check for any remaining @param@s // If there are still some in the whereclause, they will be resolved by calling the getContext() // method if (!currentWhereClause.contains("@")) { return currentWhereClause; } String localWhereClause = currentWhereClause; while (localWhereClause.contains("@")) { int firstAtIndex = localWhereClause.indexOf("@"); String prefix = localWhereClause.substring(0, firstAtIndex); String restOfClause = localWhereClause.substring(firstAtIndex + 1); int secondAtIndex = restOfClause.indexOf("@"); if (secondAtIndex == -1) { // No second @. We return the clause as it is return localWhereClause; } String suffix = restOfClause.substring(secondAtIndex + 1); String param = restOfClause.substring(0, secondAtIndex); String paramValue = Utility.getContext( new DalConnectionProvider(false), RequestContext.get().getVariablesSecureApp(), param, RequestContext.get().getRequestParameter("windowId")); localWhereClause = prefix + getTypedParameterAlias() + suffix; typedParameters.add(paramValue); } return localWhereClause; }
public void onUpdate(@Observes EntityUpdateEvent event) { if (!isValidEvent(event)) { return; } VariablesSecureApp vars = null; try { vars = RequestContext.get().getVariablesSecureApp(); } catch (Exception e) { logger.error("Error:", e); } String currentTabId = vars.getStringParameter("tabId"); if (BOM_PRODUCTION.equals(currentTabId)) { final Entity productionLineEntity = ModelProvider.getInstance().getEntity(ProductionLine.ENTITY_NAME); final BigDecimal ZERO = new BigDecimal("0"); final Property productionPlanProperty = productionLineEntity.getProperty(ProductionLine.PROPERTY_PRODUCTIONPLAN); final Property movementQtyProperty = productionLineEntity.getProperty(ProductionLine.PROPERTY_MOVEMENTQUANTITY); final ProductionPlan productionPlan = (ProductionPlan) event.getCurrentState(productionPlanProperty); final BigDecimal currentMovementQty = (BigDecimal) event.getCurrentState(movementQtyProperty); final BigDecimal previousMovementQty = (BigDecimal) event.getPreviousState(movementQtyProperty); OBCriteria<ProductionLine> productionLineCriteria = OBDal.getInstance().createCriteria(ProductionLine.class); productionLineCriteria.add( Restrictions.eq(ProductionLine.PROPERTY_PRODUCTIONPLAN, productionPlan)); productionLineCriteria.add(Restrictions.gt(ProductionLine.PROPERTY_MOVEMENTQUANTITY, ZERO)); if (productionLineCriteria.count() > 0 && previousMovementQty != currentMovementQty) { if (currentMovementQty.compareTo(ZERO) == 1 && previousMovementQty.compareTo(ZERO) != 1) { String language = OBContext.getOBContext().getLanguage().getLanguage(); ConnectionProvider conn = new DalConnectionProvider(false); throw new OBException( Utility.messageBD(conn, "@ConsumedProductWithPostiveQty@", language)); } else if (currentMovementQty.compareTo(ZERO) == -1 && previousMovementQty.compareTo(ZERO) != -1 && productionLineCriteria.count() == 1) { String language = OBContext.getOBContext().getLanguage().getLanguage(); ConnectionProvider conn = new DalConnectionProvider(false); throw new OBException( Utility.messageBD(conn, "@ProducedProductWithNegativeQty@", language)); } } } }
/** * Given a Selector object and the request parameters it evaluates the Filter Expression in case * that it is defined and returns the result. * * @param sel The Selector that it is being used. * @param parameters parameters used for this request. * @return a String with the evaluated JavaScript filter expression in case it is defined. */ private String getDefaultFilterExpression(Selector sel, Map<String, String> parameters) { if ((sel.getFilterExpression() == null || sel.getFilterExpression().equals(""))) { // Nothing to filter return ""; } Object result = null; try { result = ParameterUtils.getJSExpressionResult( parameters, RequestContext.get().getSession(), sel.getFilterExpression()); } catch (Exception e) { log.error("Error evaluating filter expression: " + e.getMessage(), e); } if (result != null && !result.toString().equals("")) { return NEW_FILTER_CLAUSE + "(" + result.toString() + ")"; } return ""; }
public static OBError openClosePeriodControl(String periodControlId) { OBError myMessage = new OBError(); OBContext.setAdminMode(true); Process process = null; try { process = OBDal.getInstance().get(Process.class, "168"); } finally { OBContext.restorePreviousMode(); } Map<String, String> parameters = new HashMap<String, String>(); final ProcessInstance pinstance = CallProcess.getInstance().call(process, periodControlId, parameters); VariablesSecureApp vars = RequestContext.get().getVariablesSecureApp(); try { ConnectionProvider conn = new DalConnectionProvider(false); myMessage = Utility.getProcessInstanceMessage( conn, vars, PInstanceProcessData.select(conn, pinstance.getId())); } catch (ServletException e) { throw new OBException("Failure getting error message", e); } return myMessage; }
/** * Returns the selectors HQL query. In case that it contains the '@additional_filters@' String it * is replaced by a set of filter clauses. * * <p>These include a filter clause: * * <ul> * <li>for the main entity's client by the context's client. * <li>for the main entity's organization by an organization list see {@link #getOrgs(String)} * <li>with Selector's default filter expression. * <li>for each default expression defined on the selector fields. * <li>for each selector field in case exists a value for it on the parameters param. * </ul> * * @param parameters Map of String values with the request parameters. * @param sel the selector that it is being retrieved the data. * @param xmlDateFormat SimpleDataFormat to be used to parse date Strings. * @return a String with the HQL to be executed. */ private String parseOptionalFilters( Map<String, String> parameters, Selector sel, SimpleDateFormat xmlDateFormat) { String HQL = sel.getHQL(); if (!HQL.contains(ADDITIONAL_FILTERS)) { return HQL; } final String requestType = parameters.get(SelectorConstants.DS_REQUEST_TYPE_PARAMETER); StringBuffer additionalFilter = new StringBuffer(); final String entityAlias = sel.getEntityAlias(); // Client filter additionalFilter .append(entityAlias + ".client.id in ('0', '") .append(OBContext.getOBContext().getCurrentClient().getId()) .append("')"); // Organization filter final String orgs = DataSourceUtils.getOrgs(parameters.get(JsonConstants.ORG_PARAMETER)); if (StringUtils.isNotEmpty(orgs)) { additionalFilter.append(NEW_FILTER_CLAUSE); additionalFilter.append( entityAlias + (sel.getTable().getName().equals("Organization") ? ".id in (" + orgs + ")" : ".organization in (" + orgs + ")")); } additionalFilter.append(getDefaultFilterExpression(sel, parameters)); StringBuffer defaultExpressionsFilter = new StringBuffer(); boolean hasFilter = false; List<SelectorField> fields = OBDao.getActiveOBObjectList(sel, Selector.PROPERTY_OBUISELSELECTORFIELDLIST); HashMap<String, String[]> criteria = getCriteria(parameters); for (SelectorField field : fields) { if (StringUtils.isEmpty(field.getClauseLeftPart())) { continue; } String operator = null; String value = null; String[] operatorvalue = null; if (criteria != null) { operatorvalue = criteria.get(field.getDisplayColumnAlias()); if (operatorvalue != null) { operator = operatorvalue[0]; value = operatorvalue[1]; } } if (StringUtils.isEmpty(value)) { value = parameters.get(field.getDisplayColumnAlias()); } // Add field default expression on picklist if it is not already filtered. Default expressions // on selector popup are already evaluated and their values came in the parameters object. if (field.getDefaultExpression() != null && !"Window".equals(requestType) && StringUtils.isEmpty(value)) { try { String defaultValue = ""; Object defaultValueObject = ParameterUtils.getJSExpressionResult( parameters, RequestContext.get().getSession(), field.getDefaultExpression()); if (defaultValueObject != null) { defaultValue = defaultValueObject.toString(); } if (StringUtils.isNotEmpty(defaultValue)) { defaultExpressionsFilter.append(NEW_FILTER_CLAUSE); defaultExpressionsFilter.append( getWhereClause(operator, defaultValue, field, xmlDateFormat, operatorvalue)); } } catch (Exception e) { log.error("Error evaluating filter expression: " + e.getMessage(), e); } } if (field.isFilterable() && StringUtils.isNotEmpty(value)) { String whereClause = getWhereClause(operator, value, field, xmlDateFormat, operatorvalue); if (!hasFilter) { additionalFilter.append(NEW_FILTER_CLAUSE); additionalFilter.append(" ("); hasFilter = true; } else { if ("Window".equals(requestType)) { additionalFilter.append(NEW_FILTER_CLAUSE); } else { additionalFilter.append(NEW_OR_FILTER_CLAUSE); } } additionalFilter.append(whereClause); } } if (hasFilter) { additionalFilter.append(")"); } if (defaultExpressionsFilter.length() > 0) { additionalFilter.append(defaultExpressionsFilter); } HQL = HQL.replace(ADDITIONAL_FILTERS, additionalFilter.toString()); return HQL; }
/** * Translate the message, searching the @ parameters, and making use of the ErrorTextParser class * to get the appropriated message. * * @param message String with the message to translate. * @return */ public static OBError translateError(String message) { VariablesSecureApp vars = RequestContext.get().getVariablesSecureApp(); final String strLanguage = OBContext.getOBContext().getLanguage().getLanguage(); return translateError(new DalConnectionProvider(false), vars, strLanguage, message); }
/** * Parse the text searching @ parameters to translate. * * @param text String with the text to translate. * @param replaceMap optional Map containing replacement values for the tokens * @return String translated. */ public static String parseTranslation(String text, Map<String, String> map) { final VariablesSecureApp vars = RequestContext.get().getVariablesSecureApp(); final String language = OBContext.getOBContext().getLanguage().getLanguage(); return parseTranslation(new DalConnectionProvider(false), vars, map, language, text); }
/** * Translates the filter criteria ({@link #addFilterParameter(String, String)}) to a valid HQL * where clause (without the 'where' keyword). After calling this method the method {@link * #getNamedParameters()} can be called. Note that currently only filtering on string and boolean * properties is supported. Also filtering on the identifier of a referenced business object is * supported. * * @return a valid where clause or an empty string if not set. */ public String getWhereClause() { if (whereClause != null) { return whereClause; } // add some default filter parameters filterParameters.put( JsonConstants.QUERY_PARAM_USER, OBContext.getOBContext().getUser().getId()); if (!filterParameters.containsKey(JsonConstants.QUERY_PARAM_CLIENT)) { filterParameters.put( JsonConstants.QUERY_PARAM_CLIENT, OBContext.getOBContext().getUser().getId()); } final SimpleDateFormat simpleDateFormat = JsonUtils.createDateFormat(); Check.isNotNull(entity, "Entity must be set"); final StringBuilder sb = new StringBuilder(); boolean addAnd = false; final StringBuilder orgPart = new StringBuilder(); final List<Property> propertyDone = new ArrayList<Property>(); String whereParameterValue = null; for (String key : filterParameters.keySet()) { String value = filterParameters.get(key); if (key.equals(JsonConstants.WHERE_PARAMETER)) { // there are cases where null is set as a string // handle this if (value.equals("null") || value.length() == 0) { continue; } whereParameterValue = value; continue; } // handle the case that we should filter on the accessible organizations if (key.equals(JsonConstants.ORG_PARAMETER)) { if (entity.isOrganizationEnabled() && value != null && value.length() > 0) { final Set<String> orgs = OBContext.getOBContext().getOrganizationStructureProvider().getNaturalTree(value); if (orgs.size() > 0) { if (getMainAlias() != null) { orgPart.append(" " + getMainAlias() + ".organization in ("); } else { orgPart.append(" organization in ("); } boolean addComma = false; for (String org : orgs) { if (addComma) { orgPart.append(","); } orgPart.append("'" + org + "'"); addComma = true; } orgPart.append(") "); } } continue; } // determine the property final List<Property> properties = JsonUtils.getPropertiesOnPath(getEntity(), key); if (properties.isEmpty()) { continue; } final Property property = properties.get(properties.size() - 1); // invalid propname, ignore this one // TODO: possibly warn about it if (property == null || propertyDone.contains(property)) { continue; } propertyDone.add(property); // we know the property and the string representation of the value... // do the conversion if (addAnd) { if (doOr) { sb.append(" or "); } else { sb.append(" and "); } } String leftWherePart = null; if (isDoOr()) { leftWherePart = resolveJoins(properties, key); } else if (getMainAlias() != null) { leftWherePart = getMainAlias() + "." + key.trim(); } else { leftWherePart = key; } // get rid of the identifier and replace it with the real property name // or with the concatenation if there are multiple parts // NOTE: the if and else check against the key variable and not the leftwherepart // because the key contains the original string (with the _identifier part). // Within the if the leftWherePart is used because it contains the join aliases if (key.equals(JsonConstants.IDENTIFIER) || key.endsWith("." + JsonConstants.IDENTIFIER)) { // the identifierProperties are read from the owning entity of the // property, that should work fine, as this last property is always part of the // identifier final List<Property> identifierProperties = property.getEntity().getIdentifierProperties(); Check.isTrue( identifierProperties.contains(property), "Property " + property + " not part of identifier of " + property.getEntity()); final String prefix; final int index = leftWherePart.lastIndexOf("."); if (key.equals(JsonConstants.IDENTIFIER)) { prefix = getMainAlias() + "."; } else if (index == -1) { prefix = ""; } else { // the + 1 makes sure that the dot is included prefix = leftWherePart.substring(0, index + 1); } leftWherePart = createIdentifierLeftClause(identifierProperties, prefix); // if the value consists of multiple parts then filtering won't work // only search on the first part then, is pragmatic but very workable if (value != null && value.contains(IdentifierProvider.SEPARATOR)) { final int separatorIndex = value.indexOf(IdentifierProvider.SEPARATOR); value = value.substring(0, separatorIndex); } } // NOTE: If you change this part, make sure that you sync the changes with the // SelectorDataSourceFilter. Check issue https://issues.openbravo.com/view.php?id=14239 // NOTE the typedParameters.add call must be done after the call to // getTypedParameterAlias, this to get the correct alias codes if (key.equals(JsonConstants.IDENTIFIER)) { if (textMatching == TextMatching.exact) { sb.append(leftWherePart + " = " + getTypedParameterAlias()); typedParameters.add(value); } else if (textMatching == TextMatching.startsWith) { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add(escapeLike(value.toUpperCase()) + "%"); } else { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add("%" + escapeLike(value.toUpperCase()).replaceAll(" ", "%") + "%"); } } else if (!property.isPrimitive()) { // an in parameter use it... if (value.contains(JsonConstants.IN_PARAMETER_SEPARATOR)) { final List<String> values = new ArrayList<String>(); final String[] separatedValues = value.split(JsonConstants.IN_PARAMETER_SEPARATOR); for (String separatedValue : separatedValues) { values.add(separatedValue); } sb.append(leftWherePart + ".id in (" + getTypedParameterAlias() + ")"); typedParameters.add(values); } else { sb.append(leftWherePart + ".id = " + getTypedParameterAlias()); typedParameters.add(value); } } else if (String.class == property.getPrimitiveObjectType()) { if (textMatching == TextMatching.exact) { sb.append(leftWherePart + " = " + getTypedParameterAlias()); typedParameters.add(value); } else if (textMatching == TextMatching.startsWith) { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add(escapeLike(value.toUpperCase()) + "%"); } else { sb.append( "upper(" + leftWherePart + ") like " + getTypedParameterAlias() + " escape '" + ESCAPE_CHAR + "' "); typedParameters.add("%" + escapeLike(value.toUpperCase()).replaceAll(" ", "%") + "%"); } } else if (Boolean.class == property.getPrimitiveObjectType()) { final String alias = getTypedParameterAlias(); typedParameters.add(new Boolean(value)); sb.append(leftWherePart + " = " + alias); } else if (property.isNumericType()) { try { final String alias = getTypedParameterAlias(); final BigDecimal bdValue = new BigDecimal(value); if (Long.class == property.getPrimitiveObjectType()) { typedParameters.add(bdValue.longValue()); } else if (Integer.class == property.getPrimitiveObjectType()) { typedParameters.add(bdValue.intValue()); } else { typedParameters.add(bdValue); } sb.append(leftWherePart + " = " + alias); } catch (NumberFormatException e) { // ignore on purpose, incorrect value entered by user // add a dummy whereclause to make the query format correct sb.append(" 1=1 "); } } else if (Date.class.isAssignableFrom(property.getPrimitiveObjectType())) { try { final Calendar cal = Calendar.getInstance(); cal.setTime(simpleDateFormat.parse(value)); final String alias1 = getTypedParameterAlias(); typedParameters.add(cal.get(Calendar.DATE)); final String alias2 = getTypedParameterAlias(); typedParameters.add(cal.get(Calendar.MONTH) + 1); final String alias3 = getTypedParameterAlias(); typedParameters.add(cal.get(Calendar.YEAR)); sb.append( " (day(" + leftWherePart + ") = " + alias1 + " and month(" + leftWherePart + ") = " + alias2 + " and year(" + leftWherePart + ") = " + alias3 + ") "); } catch (Exception e) { // ignore these errors, just don't filter then // add a dummy whereclause to make the query format correct sb.append(" 1=1 "); } // } else if (property.isDate() || property.isDatetime()) { // NOTE: dates arrive in the format of the user.... // sb.append(leftWherePart + " = ?"); // typedParameters.add(value); } else { // TODO: support this.... throw new UnsupportedOperationException( "Type " + property.getPrimitiveObjectType() + " not yet supported for parameter " + key); } addAnd = true; } log.debug("Whereclause for entity " + entity.getName()); log.debug(sb.toString()); for (Object param : typedParameters) { log.debug(param); } log.debug("Textmatching " + textMatching); if (sb.length() == 0) { whereClause = orgPart.length() > 0 ? orgPart.toString() : ""; } else { whereClause = "(" + sb.toString() + ")" + (orgPart.length() > 0 ? " and " + orgPart.toString() : ""); } if (whereParameterValue != null) { if (whereClause.length() > 0) { whereClause = " (" + whereClause + ") and (" + whereParameterValue + ") "; } else { whereClause = " " + whereParameterValue; } } if (whereClause.trim().length() > 0) { whereClause = " where " + whereClause; } // handle special transactional range parameter if (whereClause.contains(JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE)) { final String alias = getTypedParameterAlias(); String windowId = RequestContext.get().getRequestParameter("windowId"); if (windowId == null) { windowId = ""; } final String range = Utility.getTransactionalDate( new DalConnectionProvider(false), RequestContext.get().getVariablesSecureApp(), windowId); final int rangeNum = Integer.parseInt(range); final Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1 * rangeNum); whereClause = whereClause.replace(JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE, alias); typedParameters.add(cal.getTime()); } if (whereClause.contains(JsonConstants.QUERY_PARAM_CLIENT)) { final String alias = getTypedParameterAlias(); String clientId = (String) DalUtil.getId(OBContext.getOBContext().getCurrentClient()); whereClause = whereClause.replace(JsonConstants.QUERY_PARAM_CLIENT, alias); typedParameters.add(clientId); } whereClause = setRequestParameters(whereClause); whereClause = substituteContextParameters(whereClause); return whereClause; }