<commit_before>package gov.nih.nci.cagrid.data.cql.validation;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import gov.nih.nci.cagrid.cqlquery.Association;
import gov.nih.nci.cagrid.cqlquery.Attribute;
import gov.nih.nci.cagrid.cqlquery.CQLQuery;
import gov.nih.nci.cagrid.cqlquery.Group;
import gov.nih.nci.cagrid.cqlquery.Object;
import gov.nih.nci.cagrid.cqlquery.Predicate;
import gov.nih.nci.cagrid.data.MalformedQueryException;
import gov.nih.nci.cagrid.metadata.common.UMLAttribute;
import gov.nih.nci.cagrid.metadata.common.UMLClass;
import gov.nih.nci.cagrid.metadata.dataservice.DomainModel;
import gov.nih.nci.cagrid.metadata.dataservice.UMLAssociation;


/**
 * DomainModelValidator Does the dirty work of validating a CQL query against a
 * domain model
 * 
 * @author <A HREF="MAILTO:<EMAIL>"><NAME></A>
 * 
 * @created May 26, 2006
 * @version $Id$
 */
public class DomainModelValidator {

	DomainModelValidator() {

	}


	public void validateDomain(CQLQuery query, DomainModel model) throws MalformedQueryException {
		validateQueryTarget(query, model);
		validateObjectModel(query.getTarget(), model);
	}


	private void validateQueryTarget(CQLQuery query, DomainModel model) throws MalformedQueryException {
		UMLClass targetClass = getUmlClass(query.getTarget().getName(), model);
		if (targetClass == null) {
			throw new MalformedQueryException("Query target " + query.getTarget().getName()
				+ " is not a valid target in the domain model");
		}
	}


	private void validateObjectModel(Object obj, DomainModel model) throws MalformedQueryException {
		// verify the object exists in the project
		UMLClass classMd = getUmlClass(obj.getName(), model);
		if (classMd == null) {
			throw new MalformedQueryException("No object " + obj.getName() + " found in the project");
		}

		if (obj.getAttribute() != null) {
			validateAttributeModel(obj.getAttribute(), classMd);
		}

		if (obj.getAssociation() != null) {
			// ensure the association is valid
			validateAssociationModel(obj, obj.getAssociation(), model);
			// step through the association's submodel
			validateObjectModel(obj.getAssociation(), model);
		}

		if (obj.getGroup() != null) {
			validateGroupModel(obj, obj.getGroup(), model);
		}
	}


	private void validateAttributeModel(Attribute attrib, UMLClass classMd) throws MalformedQueryException {
		// verify the attribute exists
		UMLAttribute attribMd = getUmlAttribute(attrib.getName(), classMd);
		if (attribMd == null) {
			throw new MalformedQueryException("Attribute '" + attrib.getName() + "' is not defined for the class "
				+ classMd.getClassName());
		}
		// validateAttributeDataType(attrib, attribMd);
	}


	private void validateAttributeDataType(Attribute attrib, UMLAttribute attribMetadata)
		throws MalformedQueryException {
		// if the predicate is a binary operator, verify the value is
		// of the correct type
		if (attrib.getPredicate() != null
			&& !(attrib.getPredicate().getValue().equals(Predicate._IS_NOT_NULL) || attrib.getPredicate().getValue()
				.equals(Predicate._IS_NULL))) {
			String value = attrib.getValue();
			// TODO: evaluate this somehow
			/*
			 * FIXME: attributeMetadata contanins a null semantic metadata
			 * collection, so this throws null pointer exception. When that gets
			 * fixed, turn this function back on
			 */
			String dataType = attribMetadata.getSemanticMetadataCollection().getSemanticMetadata(0).getConcept()
				.getLongName();
			try {
				if (dataType.equals(Integer.class.getName())) {
					Integer.valueOf(value);
					// TODO: max / min permissable values
				} else if (dataType.equals(Long.class.getName())) {
					Long.valueOf(value);
				} else if (dataType.equals(Date.class.getName())) {
					DateFormat.getInstance().parse(value);
				} else if (dataType.equals(Boolean.class.getName())) {
					Boolean.valueOf(value);
				} else if (dataType.equals(Character.class.getName())) {
					if (value.length() != 1) {
						throw new MalformedQueryException("Characters can only be of length 1, not " + value.length());
					}
					Character.valueOf(value.charAt(0));
				}
			} catch (Exception ex) {
				throw new MalformedQueryException("Attribute " + attrib.getName() + " queried with value: " + value
					+ "; but type is " + dataType, ex);
			}
		}
	}


	private void validateAssociationModel(Object current, Association assoc, DomainModel model)
		throws MalformedQueryException {
		// determine if an association exists between the current
		// and association object
		String roleName = assoc.getRoleName();
		UMLAssociation[] associations = getUmlAssociations(current.getName(), model);
		boolean associationFound = false;
		for (int i = 0; i < associations.length; i++) {
			UMLAssociation assocMd = associations[i];
			UMLClass targetClassMd = DomainModelUtils.getReferencedUMLClass(model, assocMd
				.getTargetUMLAssociationEdge().getUMLAssociationEdge().getUMLClassReference());
			if (targetClassMd != null && targetClassMd.getClassName().equals(assoc.getName())) {
				if (associationFound) {
					// no role name, and already found an association of the
					// same type
					throw new MalformedQueryException("The association from " + current.getName() + " to "
						+ assoc.getName() + " is ambiguous without a role name");
				}
				if (roleName != null) {
					if (assocMd.getTargetUMLAssociationEdge().getUMLAssociationEdge().getRoleName().equals(roleName)) {
						associationFound = true;
						break;
					}
				}
			}
		}
		if (!associationFound) {
			throw new MalformedQueryException("No association from " + current.getName() + " to " + assoc.getName()
				+ " with role name " + assoc.getRoleName());
		}
	}


	private void validateGroupModel(Object current, Group group, DomainModel model) throws MalformedQueryException {
		if (group.getAttribute() != null) {
			UMLClass classMd = getUmlClass(current.getName(), model);
			for (int i = 0; i < group.getAttribute().length; i++) {
				validateAttributeModel(group.getAttribute(i), classMd);
			}
		}

		if (group.getAssociation() != null) {
			for (int i = 0; i < group.getAssociation().length; i++) {
				validateAssociationModel(current, group.getAssociation(i), model);
			}
		}

		if (group.getGroup() != null) {
			for (int i = 0; i < group.getGroup().length; i++) {
				validateGroupModel(current, group.getGroup(i), model);
			}
		}
	}


	private UMLClass getUmlClass(String className, DomainModel model) {
		UMLClass[] allClasses = model.getExposedUMLClassCollection().getUMLClass();

		for (int i = 0; allClasses != null && i < allClasses.length; i++) {
			String fqn = allClasses[i].getPackageName().trim();
			if (!fqn.equals("")) {
				fqn += "." + allClasses[i].getClassName();
			}

			if (fqn.equals(className)) {
				return allClasses[i];
			}
		}
		return null;
	}


	private UMLAttribute getUmlAttribute(String attribName, UMLClass classMd) {
		UMLAttribute[] attribs = classMd.getUmlAttributeCollection().getUMLAttribute();
		for (int i = 0; attribs != null && i < attribs.length; i++) {
			UMLAttribute attrib = attribs[i];
			String fullAttribName = attrib.getName();
			int shortIndex = fullAttribName.indexOf(":");
			String shortAttribName = fullAttribName.substring(shortIndex + 1);
			if (shortAttribName.equals(attribName)) {
				return attrib;
			}
		}
		return null;
	}


	private UMLAssociation[] getUmlAssociations(String sourceClass, DomainModel model) {
		List associations = new ArrayList();
		if (model.getExposedUMLAssociationCollection() != null
			&& model.getExposedUMLAssociationCollection().getUMLAssociation() != null) {
			for (int i = 0; i < model.getExposedUMLAssociationCollection().getUMLAssociation().length; i++) {
				UMLAssociation assoc = model.getExposedUMLAssociationCollection().getUMLAssociation(i);

				UMLClass referencedUMLClass = DomainModelUtils.getReferencedUMLClass(model, assoc
					.getSourceUMLAssociationEdge().getUMLAssociationEdge().getUMLClassReference());
				if (referencedUMLClass != null && referencedUMLClass.getClassName().equals(sourceClass)) {
					associations.add(assoc);
				}
			}
		}
		UMLAssociation[] array = new UMLAssociation[associations.size()];
		associations.toArray(array);
		return array;
	}
}
<commit_msg>*** empty log message ***<commit_after>package gov.nih.nci.cagrid.data.cql.validation;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import gov.nih.nci.cadsr.umlproject.domain.SemanticMetadata;
import gov.nih.nci.cagrid.cqlquery.Association;
import gov.nih.nci.cagrid.cqlquery.Attribute;
import gov.nih.nci.cagrid.cqlquery.CQLQuery;
import gov.nih.nci.cagrid.cqlquery.Group;
import gov.nih.nci.cagrid.cqlquery.Object;
import gov.nih.nci.cagrid.cqlquery.Predicate;
import gov.nih.nci.cagrid.data.MalformedQueryException;
import gov.nih.nci.cagrid.metadata.common.UMLAttribute;
import gov.nih.nci.cagrid.metadata.common.UMLClass;
import gov.nih.nci.cagrid.metadata.dataservice.DomainModel;
import gov.nih.nci.cagrid.metadata.dataservice.UMLAssociation;


/**
 * DomainModelValidator Does the dirty work of validating a CQL query against a
 * domain model
 * 
 * @author <A HREF="MAILTO:<EMAIL>"><NAME></A>
 * 
 * @created May 26, 2006
 * @version $Id$
 */
public class DomainModelValidator {

	DomainModelValidator() {

	}


	public void validateDomain(CQLQuery query, DomainModel model) throws MalformedQueryException {
		validateQueryTarget(query, model);
		validateObjectModel(query.getTarget(), model);
	}


	private void validateQueryTarget(CQLQuery query, DomainModel model) throws MalformedQueryException {
		UMLClass targetClass = getUmlClass(query.getTarget().getName(), model);
		if (targetClass == null) {
			throw new MalformedQueryException("Query target " + query.getTarget().getName()
				+ " is not a valid target in the domain model");
		}
	}


	private void validateObjectModel(Object obj, DomainModel model) throws MalformedQueryException {
		// verify the object exists in the project
		UMLClass classMd = getUmlClass(obj.getName(), model);
		if (classMd == null) {
			throw new MalformedQueryException("No object " + obj.getName() + " found in the project");
		}

		if (obj.getAttribute() != null) {
			validateAttributeModel(obj.getAttribute(), classMd);
		}

		if (obj.getAssociation() != null) {
			// ensure the association is valid
			validateAssociationModel(obj, obj.getAssociation(), model);
			// step through the association's submodel
			validateObjectModel(obj.getAssociation(), model);
		}

		if (obj.getGroup() != null) {
			validateGroupModel(obj, obj.getGroup(), model);
		}
	}


	private void validateAttributeModel(Attribute attrib, UMLClass classMd) throws MalformedQueryException {
		// verify the attribute exists
		UMLAttribute attribMd = getUmlAttribute(attrib.getName(), classMd);
		if (attribMd == null) {
			throw new MalformedQueryException("Attribute '" + attrib.getName() + "' is not defined for the class "
				+ classMd.getClassName());
		}
	}


	private void validateAttributeDataType(Attribute attrib, UMLAttribute attribMetadata)
		throws MalformedQueryException {
		// if the predicate is a binary operator, verify the value is of the correct type
		if (attrib.getPredicate() != null
			&& !(attrib.getPredicate().getValue().equals(Predicate._IS_NOT_NULL) 
				|| attrib.getPredicate().getValue().equals(Predicate._IS_NULL))) {
			String value = attrib.getValue();
			// FIXME: This isn't right.  UMLAttributeMetadata has
			// getDataElement().getValueDomain().getDatatypeName(), which is what I need
			SemanticMetadata semanticMd = attribMetadata.getSemanticMetadataCollection().getSemanticMetadata(0); 
			String dataType = semanticMd.getConcept().getLongName();
			try {
				if (dataType.equals(Integer.class.getName())) {
					Integer.valueOf(value);
					// TODO: max / min permissable values
				} else if (dataType.equals(Long.class.getName())) {
					Long.valueOf(value);
				} else if (dataType.equals(Date.class.getName())) {
					DateFormat.getInstance().parse(value);
				} else if (dataType.equals(Boolean.class.getName())) {
					Boolean.valueOf(value);
				} else if (dataType.equals(Character.class.getName())) {
					if (value.length() != 1) {
						throw new MalformedQueryException("Characters can only be of length 1, not " + value.length());
					}
					Character.valueOf(value.charAt(0));
				}
			} catch (Exception ex) {
				throw new MalformedQueryException("Attribute " + attrib.getName() + " queried with value: " 
					+ value + "; but type is " + dataType, ex);
			}
		}
	}


	private void validateAssociationModel(Object current, Association assoc, DomainModel model)
		throws MalformedQueryException {
		// determine if an association exists between the current
		// and association object
		String roleName = assoc.getRoleName();
		UMLAssociation[] associations = getUmlAssociations(current.getName(), model);
		boolean associationFound = false;
		for (int i = 0; i < associations.length; i++) {
			UMLAssociation assocMd = associations[i];
			UMLClass targetClassMd = DomainModelUtils.getReferencedUMLClass(model, assocMd
				.getTargetUMLAssociationEdge().getUMLAssociationEdge().getUMLClassReference());
			if (targetClassMd != null && targetClassMd.getClassName().equals(assoc.getName())) {
				if (associationFound) {
					// no role name, and already found an association of the
					// same type
					throw new MalformedQueryException("The association from " + current.getName() + " to "
						+ assoc.getName() + " is ambiguous without a role name");
				}
				if (roleName != null) {
					if (assocMd.getTargetUMLAssociationEdge().getUMLAssociationEdge().getRoleName().equals(roleName)) {
						associationFound = true;
						break;
					}
				}
			}
		}
		if (!associationFound) {
			throw new MalformedQueryException("No association from " + current.getName() + " to " + assoc.getName()
				+ " with role name " + assoc.getRoleName());
		}
	}


	private void validateGroupModel(Object current, Group group, DomainModel model) throws MalformedQueryException {
		if (group.getAttribute() != null) {
			UMLClass classMd = getUmlClass(current.getName(), model);
			for (int i = 0; i < group.getAttribute().length; i++) {
				validateAttributeModel(group.getAttribute(i), classMd);
			}
		}

		if (group.getAssociation() != null) {
			for (int i = 0; i < group.getAssociation().length; i++) {
				validateAssociationModel(current, group.getAssociation(i), model);
			}
		}

		if (group.getGroup() != null) {
			for (int i = 0; i < group.getGroup().length; i++) {
				validateGroupModel(current, group.getGroup(i), model);
			}
		}
	}


	private UMLClass getUmlClass(String className, DomainModel model) {
		UMLClass[] allClasses = model.getExposedUMLClassCollection().getUMLClass();

		for (int i = 0; allClasses != null && i < allClasses.length; i++) {
			String fqn = allClasses[i].getPackageName().trim();
			if (!fqn.equals("")) {
				fqn += "." + allClasses[i].getClassName();
			}

			if (fqn.equals(className)) {
				return allClasses[i];
			}
		}
		return null;
	}


	private UMLAttribute getUmlAttribute(String attribName, UMLClass classMd) {
		UMLAttribute[] attribs = classMd.getUmlAttributeCollection().getUMLAttribute();
		for (int i = 0; attribs != null && i < attribs.length; i++) {
			UMLAttribute attrib = attribs[i];
			String fullAttribName = attrib.getName();
			int shortIndex = fullAttribName.indexOf(":");
			String shortAttribName = fullAttribName.substring(shortIndex + 1);
			if (shortAttribName.equals(attribName)) {
				return attrib;
			}
		}
		return null;
	}


	private UMLAssociation[] getUmlAssociations(String sourceClass, DomainModel model) {
		List associations = new ArrayList();
		if (model.getExposedUMLAssociationCollection() != null
			&& model.getExposedUMLAssociationCollection().getUMLAssociation() != null) {
			for (int i = 0; i < model.getExposedUMLAssociationCollection().getUMLAssociation().length; i++) {
				UMLAssociation assoc = model.getExposedUMLAssociationCollection().getUMLAssociation(i);

				UMLClass referencedUMLClass = DomainModelUtils.getReferencedUMLClass(model, assoc
					.getSourceUMLAssociationEdge().getUMLAssociationEdge().getUMLClassReference());
				if (referencedUMLClass != null && referencedUMLClass.getClassName().equals(sourceClass)) {
					associations.add(assoc);
				}
			}
		}
		UMLAssociation[] array = new UMLAssociation[associations.size()];
		associations.toArray(array);
		return array;
	}
}

{'fraction_non_alphanumeric': 0.12533349502789232, 'fraction_numerical': 0.00218287654620422, 'mean_word_length': 4.3186069009996775, 'pattern_counts': {'":': 2, '<': 25, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1095825', 'n_tokens_mistral': 5827, 'n_tokens_neox': 5020, 'n_words': 1134}