<commit_before>/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.api.APIException;
import org.openmrs.api.ConceptNameType;
import org.openmrs.api.ConceptService;
import org.openmrs.api.context.Context;
import org.openmrs.util.LocaleUtility;
import org.openmrs.util.OpenmrsUtil;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import org.springframework.util.ObjectUtils;

/**
 * A Concept object can represent either a question or an answer to a data point. That data point is
 * usually an {@link Obs}. <br/>
 * <br/>
 * A Concept can have multiple names and multiple descriptions within one locale and across multiple
 * locales.<br/>
 * <br/>
 * To save a Concept to the database, first build up the Concept object in java, then pass that
 * object to the {@link ConceptService}.<br/>
 * <br/>
 * To get a Concept that is stored in the database, call a method in the {@link ConceptService} to
 * fetch an object. To get child objects off of that Concept, further calls to the
 * {@link ConceptService} or the database are not needed. e.g. To get the list of answers that are
 * stored to a concept, get the concept, then call {@link Concept#getAnswers()}
 * 
 * @see ConceptName
 * @see ConceptDescription
 * @see ConceptAnswer
 * @see ConceptSet
 * @see ConceptMap
 * @see ConceptService
 */
@Root
public class Concept extends BaseOpenmrsObject implements Auditable, Retireable, java.io.Serializable, Attributable<Concept> {
	
	public static final long serialVersionUID = 57332L;
	
	private static final Log log = LogFactory.getLog(Concept.class);
	
	// Fields
	
	private Integer conceptId;
	
	private Boolean retired = false;
	
	private User retiredBy;
	
	private Date dateRetired;
	
	private String retireReason;
	
	private ConceptDatatype datatype;
	
	private ConceptClass conceptClass;
	
	private Boolean set = false;
	
	private String version;
	
	private User creator;
	
	private Date dateCreated;
	
	private User changedBy;
	
	private Date dateChanged;
	
	private Collection<ConceptName> names;
	
	private Collection<ConceptAnswer> answers;
	
	private Collection<ConceptSet> conceptSets;
	
	private Collection<ConceptDescription> descriptions;
	
	private Collection<ConceptMap> conceptMappings;
	
	/**
	 * A cache of locales to names which have compatible locales. Built on-the-fly by
	 * getCompatibleNames().
	 */
	private Map<Locale, List<ConceptName>> compatibleCache;
	
	/** default constructor */
	public Concept() {
		names = new HashSet<ConceptName>();
		answers = new HashSet<ConceptAnswer>();
		conceptSets = new TreeSet<ConceptSet>();
		descriptions = new HashSet<ConceptDescription>();
		conceptMappings = new HashSet<ConceptMap>();
	}
	
	/**
	 * Convenience constructor with conceptid to save to {@link #setConceptId(Integer)}. This
	 * effectively creates a concept stub that can be used to make other calls. Because the
	 * {@link #equals(Object)} and {@link #hashCode()} methods rely on conceptId, this allows a stub
	 * to masquerade as a full concept as long as other objects like {@link #getAnswers()} and
	 * {@link #getNames()} are not needed/called.
	 * 
	 * @param conceptId the concept id to set
	 */
	public Concept(Integer conceptId) {
		this.conceptId = conceptId;
	}
	
	/**
	 * Possibly used for decapitating a ConceptNumeric (to remove the row in concept_numeric)
	 * 
	 * @param cn
	 * @deprecated
	 */
	@Deprecated
	public Concept(ConceptNumeric cn) {
		conceptId = cn.getConceptId();
		retired = cn.isRetired();
		datatype = cn.getDatatype();
		conceptClass = cn.getConceptClass();
		version = cn.getVersion();
		creator = cn.getCreator();
		dateCreated = cn.getDateCreated();
		changedBy = cn.getChangedBy();
		dateChanged = cn.getDateChanged();
		names = cn.getNames();
		descriptions = cn.getDescriptions();
		answers = cn.getAnswers(true);
		conceptSets = cn.getConceptSets();
		conceptMappings = cn.getConceptMappings();
		setUuid(cn.getUuid());
	}
	
	/**<commit_msg>TRUNK-3904: Concept(Integer) constructer doesn't call this()<commit_after>/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.api.APIException;
import org.openmrs.api.ConceptNameType;
import org.openmrs.api.ConceptService;
import org.openmrs.api.context.Context;
import org.openmrs.util.LocaleUtility;
import org.openmrs.util.OpenmrsUtil;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import org.springframework.util.ObjectUtils;

/**
 * A Concept object can represent either a question or an answer to a data point. That data point is
 * usually an {@link Obs}. <br/>
 * <br/>
 * A Concept can have multiple names and multiple descriptions within one locale and across multiple
 * locales.<br/>
 * <br/>
 * To save a Concept to the database, first build up the Concept object in java, then pass that
 * object to the {@link ConceptService}.<br/>
 * <br/>
 * To get a Concept that is stored in the database, call a method in the {@link ConceptService} to
 * fetch an object. To get child objects off of that Concept, further calls to the
 * {@link ConceptService} or the database are not needed. e.g. To get the list of answers that are
 * stored to a concept, get the concept, then call {@link Concept#getAnswers()}
 * 
 * @see ConceptName
 * @see ConceptDescription
 * @see ConceptAnswer
 * @see ConceptSet
 * @see ConceptMap
 * @see ConceptService
 */
@Root
public class Concept extends BaseOpenmrsObject implements Auditable, Retireable, java.io.Serializable, Attributable<Concept> {
	
	public static final long serialVersionUID = 57332L;
	
	private static final Log log = LogFactory.getLog(Concept.class);
	
	// Fields
	
	private Integer conceptId;
	
	private Boolean retired = false;
	
	private User retiredBy;
	
	private Date dateRetired;
	
	private String retireReason;
	
	private ConceptDatatype datatype;
	
	private ConceptClass conceptClass;
	
	private Boolean set = false;
	
	private String version;
	
	private User creator;
	
	private Date dateCreated;
	
	private User changedBy;
	
	private Date dateChanged;
	
	private Collection<ConceptName> names;
	
	private Collection<ConceptAnswer> answers;
	
	private Collection<ConceptSet> conceptSets;
	
	private Collection<ConceptDescription> descriptions;
	
	private Collection<ConceptMap> conceptMappings;
	
	/**
	 * A cache of locales to names which have compatible locales. Built on-the-fly by
	 * getCompatibleNames().
	 */
	private Map<Locale, List<ConceptName>> compatibleCache;
	
	/** default constructor */
	public Concept() {
		names = new HashSet<ConceptName>();
		answers = new HashSet<ConceptAnswer>();
		conceptSets = new TreeSet<ConceptSet>();
		descriptions = new HashSet<ConceptDescription>();
		conceptMappings = new HashSet<ConceptMap>();
	}
	
	/**
	 * Convenience constructor with conceptid to save to {@link #setConceptId(Integer)}. This
	 * effectively creates a concept stub that can be used to make other calls. Because the
	 * {@link #equals(Object)} and {@link #hashCode()} methods rely on conceptId, this allows a stub
	 * to masquerade as a full concept as long as other objects like {@link #getAnswers()} and
	 * {@link #getNames()} are not needed/called.
	 * 
	 * @param conceptId the concept id to set
	 */
	public Concept(Integer conceptId) {
		this();
		this.conceptId = conceptId;
	}
	
	/**
	 * Possibly used for decapitating a ConceptNumeric (to remove the row in concept_numeric)
	 * 
	 * @param cn
	 * @deprecated
	 */
	@Deprecated
	public Concept(ConceptNumeric cn) {
		conceptId = cn.getConceptId();
		retired = cn.isRetired();
		datatype = cn.getDatatype();
		conceptClass = cn.getConceptClass();
		version = cn.getVersion();
		creator = cn.getCreator();
		dateCreated = cn.getDateCreated();
		changedBy = cn.getChangedBy();
		dateChanged = cn.getDateChanged();
		names = cn.getNames();
		descriptions = cn.getDescriptions();
		answers = cn.getAnswers(true);
		conceptSets = cn.getConceptSets();
		conceptMappings = cn.getConceptMappings();
		setUuid(cn.getUuid());
	}
	
	/**
{'fraction_non_alphanumeric': 0.0965094432908138, 'fraction_numerical': 0.0017798872738059924, 'mean_word_length': 4.362672322375397, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, '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': '662004', 'n_tokens_mistral': 3156, 'n_tokens_neox': 2889, 'n_words': 1028}