container/components/components/src/main/java/org/mobicents/slee/container/component/validator/ProfileSpecificationComponentValidator.java
boolean validateExpression(String queryName, QueryExpressionDescriptor expression,

	Set<String> usedQueryParameter, Set<String> cmpFieldNames,
			Set<String> collatorAliasses) {
		boolean passed = true;
		String attributeName = null;
		String collatorRef = null;
		String parameter = null;
		String value = null;
		boolean ignoreAbsence = false;

		// We dont have access to type of cmp, we just simply check parameter

		String errorBuffer = new String("");
		try {
			switch (expression.getType()) {
			// "complex types"
			case And:
				for (QueryExpressionDescriptor mqe : expression.getAnd()) {
					if (!validateExpression(queryName, mqe, usedQueryParameter,
							cmpFieldNames, collatorAliasses)) {
						passed = false;
					}
				}
				break;
			case Or:
				for (QueryExpressionDescriptor mqe : expression.getOr()) {
					if (!validateExpression(queryName, mqe, usedQueryParameter,
							cmpFieldNames, collatorAliasses)) {
						passed = false;
					}
				}
				break;
			// "simple" types
			case Not:
				// this is one akward case :)
				if (!validateExpression(queryName, expression.getNot(),
						usedQueryParameter, cmpFieldNames, collatorAliasses)) {
					passed = false;
				}

				break;

			case Compare:
				attributeName = expression.getCompare().getAttributeName();
				collatorRef = expression.getCompare().getCollatorRef();
				parameter = expression.getCompare().getParameter();
				value = expression.getCompare().getValue();

				break;
			case HasPrefix:
				attributeName = expression.getHasPrefix().getAttributeName();
				collatorRef = expression.getHasPrefix().getCollatorRef();
				parameter = expression.getHasPrefix().getParameter();
				value = expression.getHasPrefix().getValue();
				break;
			case LongestPrefixMatch:
				attributeName = expression.getLongestPrefixMatch()
						.getAttributeName();
				collatorRef = expression.getLongestPrefixMatch()
						.getCollatorRef();
				parameter = expression.getLongestPrefixMatch().getParameter();
				value = expression.getLongestPrefixMatch().getValue();
				break;
			case RangeMatch:
				attributeName = expression.getRangeMatch().getAttributeName();
				collatorRef = expression.getRangeMatch().getCollatorRef();

				RangeMatchDescriptor mrm = expression.getRangeMatch();

				ignoreAbsence = true;
				if (mrm.getFromParameter() == null
						&& mrm.getFromValue() == null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either fromValue or fromParameter can be present, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (mrm.getFromParameter() != null
						&& mrm.getFromValue() != null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either fromValue or fromParameter can be present, not both, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (mrm.getToParameter() == null && mrm.getToValue() == null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either toValue or toParameter can be present, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (mrm.getToParameter() != null && mrm.getToValue() != null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either toValue or toParameter can be present, not both, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}
				if (mrm.getFromParameter() != null) {
					usedQueryParameter.add(mrm.getFromParameter());
				}

				if (mrm.getToParameter() != null) {
					usedQueryParameter.add(mrm.getToParameter());
				}

				break;
			}

			//This will hapen for Not,And, Or operators
			if (attributeName != null) {
				if (!Character.isLowerCase(attributeName.charAt(0))) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query usage of cmp attribute that is not valid cmp identifier, declared cmp field: "
									+ attributeName
									+ ", query name: "
									+ queryName, "10.20.2", errorBuffer);
				} else if (!cmpFieldNames.contains(attributeName) && !checkForCmpMethodFromFieldName(attributeName)) {
					
					//we have to check this. stupid specs for profile cmps are not so strict..... You can defined CMP methods but not define them in descriptor.....!!!!!!!
					
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query usage of cmp field that does not exist(its not declared in descritpro and in cmp interface), declared cmp field: "
									+ attributeName
									+ ", query name: "
									+ queryName, "10.20.2", errorBuffer);
					
				}
				if (collatorRef != null
						&& !collatorAliasses.contains(collatorRef)) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query usage of collator that is not aliased, collator alias: "
									+ collatorRef
									+ ", query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (!ignoreAbsence && parameter != null && value != null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, value and parameter can not be present at the same time, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (!ignoreAbsence && parameter == null && value == null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either value or parameter must be present, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}
				if (parameter != null) {
					usedQueryParameter.add(parameter);
				}
			}

		} finally {

			if (!passed) {
				if(logger.isEnabledFor(Level.ERROR))
					logger.error(errorBuffer);
				//System.err.println(errorBuffer);
			}

		}

		return passed;
	}
boolean validateExpression(String queryName, QueryExpressionDescriptor expression,

	Set<String> usedQueryParameter, Set<String> cmpFieldNames,
			Set<String> collatorAliasses) {
		boolean passed = true;
		String attributeName = null;
		String collatorRef = null;
		String parameter = null;
		String value = null;
		boolean ignoreAbsence = false;

		// We dont have access to type of cmp, we just simply check parameter

		String errorBuffer = new String("");
		try {
			switch (expression.getType()) {
			// "complex types"
			case And:
				for (QueryExpressionDescriptor mqe : expression.getAnd()) {
					if (!validateExpression(queryName, mqe, usedQueryParameter,
							cmpFieldNames, collatorAliasses)) {
						passed = false;
					}
				}
				break;
			case Or:
				for (QueryExpressionDescriptor mqe : expression.getOr()) {
					if (!validateExpression(queryName, mqe, usedQueryParameter,
							cmpFieldNames, collatorAliasses)) {
						passed = false;
					}
				}
				break;
			// "simple" types
			case Not:
				// this is one akward case :)
				if (!validateExpression(queryName, expression.getNot(),
						usedQueryParameter, cmpFieldNames, collatorAliasses)) {
					passed = false;
				}

				break;

			case Compare:
				attributeName = expression.getCompare().getAttributeName();
				collatorRef = expression.getCompare().getCollatorRef();
				parameter = expression.getCompare().getParameter();
				value = expression.getCompare().getValue();

				break;
			case HasPrefix:
				attributeName = expression.getHasPrefix().getAttributeName();
				collatorRef = expression.getHasPrefix().getCollatorRef();
				parameter = expression.getHasPrefix().getParameter();
				value = expression.getHasPrefix().getValue();
				break;
			case LongestPrefixMatch:
				attributeName = expression.getLongestPrefixMatch()
						.getAttributeName();
				collatorRef = expression.getLongestPrefixMatch()
						.getCollatorRef();
				parameter = expression.getLongestPrefixMatch().getParameter();
				value = expression.getLongestPrefixMatch().getValue();
				break;
			case RangeMatch:
				attributeName = expression.getRangeMatch().getAttributeName();
				collatorRef = expression.getRangeMatch().getCollatorRef();

				RangeMatchDescriptor mrm = expression.getRangeMatch();

				ignoreAbsence = true;
				if (mrm.getFromParameter() == null
						&& mrm.getFromValue() == null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either fromValue or fromParameter can be present, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (mrm.getFromParameter() != null
						&& mrm.getFromValue() != null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either fromValue or fromParameter can be present, not both, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (mrm.getToParameter() == null && mrm.getToValue() == null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either toValue or toParameter can be present, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (mrm.getToParameter() != null && mrm.getToValue() != null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either toValue or toParameter can be present, not both, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}
				if (mrm.getFromParameter() != null) {
					usedQueryParameter.add(mrm.getFromParameter());
				}

				if (mrm.getToParameter() != null) {
					usedQueryParameter.add(mrm.getToParameter());
				}

				break;
			}

			//This will hapen for Not,And, Or operators
			if (attributeName != null) {
				if (!Character.isLowerCase(attributeName.charAt(0))) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query usage of cmp attribute that is not valid cmp identifier, declared cmp field: "
									+ attributeName
									+ ", query name: "
									+ queryName, "10.20.2", errorBuffer);
				} else if (!cmpFieldNames.contains(attributeName) && !checkForCmpMethodFromFieldName(attributeName)) {
					
					//we have to check this. stupid specs for profile cmps are not so strict..... You can defined CMP methods but not define them in descriptor.....!!!!!!!
					
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query usage of cmp field that does not exist(its not declared in descritpro and in cmp interface), declared cmp field: "
									+ attributeName
									+ ", query name: "
									+ queryName, "10.20.2", errorBuffer);
					
				}
				if (collatorRef != null
						&& !collatorAliasses.contains(collatorRef)) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query usage of collator that is not aliased, collator alias: "
									+ collatorRef
									+ ", query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (!ignoreAbsence && parameter != null && value != null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, value and parameter can not be present at the same time, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}

				if (!ignoreAbsence && parameter == null && value == null) {
					passed = false;
					errorBuffer = appendToBuffer(
							"Profile specification declares in static query wrong properties, either value or parameter must be present, query name: "
									+ queryName, "10.20.2", errorBuffer);
				}
				if (parameter != null) {
					usedQueryParameter.add(parameter);
				}
			}

		} finally {

			if (!passed) {
				if(logger.isEnabledFor(Level.ERROR))
					logger.error(errorBuffer);
				//System.err.println(errorBuffer);
			}

		}

		return passed;
	}
Checks expression to check if collator refs and cmp fields are referenced
correctly. type constraints are checked later. Since in case of lack of
parameter we have to relly totaly on CMP field type. Additionaly this
check if parameter and value are present together.

@param queryName
@param cmpInterfaceClass
@param expression
@param decalredQueryParameter
@param usedQueryParameter
@return