<commit_before>package dbnp.studycapturing

import dbnp.user.User

/**
 * The Template class describes a TemplateEntity template, which is basically an extension of the study capture entities
 * in terms of extra fields (which are described by classes that extend the TemplateField class).
 * Study, Subject, Sample and Event are all TemplateEntities.
 *
 * Within a Template, we have two different types of fields: 'domain fields' and 'template fields'.
 * The domain fields are TemplateFields which are given by the TemplateEntity itself and therefore always present
 * in any instance of that TemplateEntity. They are specified by implementing TemplateEntity.giveDomainFields()
 * The template fields are TemplateFields which are added specifically by the Template. They are specified
 * in the fields property of the Template object which is referenced by the TemplateEntity.template property.
 *
 * Revision information:
 * $Rev$
 * $Author$
 * $Date$
 */
class Template extends Identity {

	/** The name of the template */
	String name

	/** A string describing the template to other users */
	String description

	/** The target TemplateEntity for this template */
	Class entity

	/** The owner of the template. If the owner is not defined, it is a shared/public template */
	User owner

	/** The template fields which are the members of this template. This is a List to preserve the field order */
	List fields

	static hasMany = [fields: TemplateField]

	// constraints
	static constraints = {
		owner(nullable: true, blank: true)
		description(nullable: true, blank: true)

		fields(validator: { fields, obj, errors ->
			// 'obj' refers to the actual Template object

			// define a boolean
			def error = false

			// iterate through fields
			fields.each { field ->
				// check if the field entity is the same as the template entity
				if (!field.entity.equals(obj.entity)) {
					error = true
					errors.rejectValue(
						'fields',
						'templateEntity.entityMismatch',
						[field.name, obj.entity, field.entity] as Object[],
						'Template field {0} must be of entity {1} and is currently of entity {2}'
						)
				}
			}

			// got an error, or not?
			return (!error)
		})

		// outcommented for now due to bug in Grails / Hibernate
		// see http://jira.codehaus.org/browse/GRAILS-6020
		// This is to verify that the template name is unique with respect to the parent entity.
		// TODO: this probably has to change in the case of private templates of different users,
		// which can co-exist with the same name. See also TemplateField
		//	name(unique:['entity'])
	}

	/**
	 * overloaded toString method
	 * @return String<commit_msg>workaround for checking Template name uniqueness<commit_after>package dbnp.studycapturing

import dbnp.user.User

/**
 * The Template class describes a TemplateEntity template, which is basically an extension of the study capture entities
 * in terms of extra fields (which are described by classes that extend the TemplateField class).
 * Study, Subject, Sample and Event are all TemplateEntities.
 *
 * Within a Template, we have two different types of fields: 'domain fields' and 'template fields'.
 * The domain fields are TemplateFields which are given by the TemplateEntity itself and therefore always present
 * in any instance of that TemplateEntity. They are specified by implementing TemplateEntity.giveDomainFields()
 * The template fields are TemplateFields which are added specifically by the Template. They are specified
 * in the fields property of the Template object which is referenced by the TemplateEntity.template property.
 *
 * Revision information:
 * $Rev$
 * $Author$
 * $Date$
 */
class Template extends Identity {

	/** The name of the template */
	String name

	/** A string describing the template to other users */
	String description

	/** The target TemplateEntity for this template */
	Class entity

	/** The owner of the template. If the owner is not defined, it is a shared/public template */
	User owner

	/** The template fields which are the members of this template. This is a List to preserve the field order */
	List fields

	static hasMany = [fields: TemplateField]

	// constraints
	static constraints = {
		owner(nullable: true, blank: true)
		description(nullable: true, blank: true)

		fields(validator: { fields, obj, errors ->
			// 'obj' refers to the actual Template object

			// define a boolean
			def error = false

			// iterate through fields
			fields.each { field ->
				// check if the field entity is the same as the template entity
				if (!field.entity.equals(obj.entity)) {
					error = true
					errors.rejectValue(
						'fields',
						'templateEntity.entityMismatch',
						[field.name, obj.entity, field.entity] as Object[],
						'Template field {0} must be of entity {1} and is currently of entity {2}'
						)
				}
			}

			// got an error, or not?
			return (!error)
		})

		// outcommented for now due to bug in Grails / Hibernate
		// see http://jira.codehaus.org/browse/GRAILS-6020
		// This is to verify that the template name is unique with respect to the parent entity.
		// TODO: this probably has to change in the case of private templates of different users,
		// which can co-exist with the same name. See also TemplateField
		// name(unique:['entity'])
		// workaround:
		name(validator: { value, obj, errors ->
			// 'obj' refers to the actual Template object

			// define a boolean
			boolean error = false

			if (value && obj.entity) {

				// gather all Cars with this particular model
				def entityTemplates = Template.findAllByEntity(obj.entity)

				// check if there is already a Template object with this name in that collection
				if (entityTemplates.findAll{it.name.equals(value)}.size() > 0) {
					errors.rejectValue(
						'name',
						'template.UniqueNameViolation',
						[value, obj.entity] as Object[],
						'There already exists a template named {0} for entity {1}'
					)
					error = true
				}
			}
			else {
				// if there is no name or model defined, fail immediately
				error = true
			}
			// got an error, or not?
			if (error) return false
		})

	}

	/**
	 * overloaded toString method
	 * @return String
{'fraction_non_alphanumeric': 0.08244422890397672, 'fraction_numerical': 0.002748140963465891, 'mean_word_length': 3.2434842249657065, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '5931684', 'n_tokens_mistral': 1846, 'n_tokens_neox': 1599, 'n_words': 753}