<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.api.context;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aopalliance.aop.Advice;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.api.APIException;
import org.openmrs.api.ActiveListService;
import org.openmrs.api.AdministrationService;
import org.openmrs.api.CohortService;
import org.openmrs.api.ConceptService;
import org.openmrs.api.DataSetService;
import org.openmrs.api.EncounterService;
import org.openmrs.api.FormService;
import org.openmrs.api.LocationService;
import org.openmrs.api.ObsService;
import org.openmrs.api.OrderService;
import org.openmrs.api.PatientService;
import org.openmrs.api.PatientSetService;
import org.openmrs.api.PersonService;
import org.openmrs.api.ProgramWorkflowService;
import org.openmrs.api.ReportService;
import org.openmrs.api.SerializationService;
import org.openmrs.api.UserService;
import org.openmrs.arden.ArdenService;
import org.openmrs.hl7.HL7Service;
import org.openmrs.logic.LogicService;
import org.openmrs.messagesource.MessageSourceService;
import org.openmrs.notification.AlertService;
import org.openmrs.notification.MessageService;
import org.openmrs.reporting.ReportObjectService;
import org.openmrs.scheduler.SchedulerService;
import org.openmrs.util.OpenmrsClassLoader;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * Represents an OpenMRS <code>Service Context</code>, which returns the services represented
 * throughout the system. <br/>
 * <br/>
 * This class should not be access directly, but rather used through the <code>Context</code> class. <br/>
 * <br/>
 * This class is essentially static and only one instance is kept because this is fairly
 * heavy-weight. Spring takes care of filling in the actual service implementations via dependency
 * injection. See the /metadata/api/spring/applicationContext-service.xml file. <br/>
 * <br/>
 * Module services are also accessed through this class. See {@link #getService(Class)}
 * 
 * @see org.openmrs.api.context.Context
 */
public class ServiceContext implements ApplicationContextAware {
	
	private static final Log log = LogFactory.getLog(ServiceContext.class);
	
	private static ServiceContext instance;
	
	private ApplicationContext applicationContext;
	
	private Boolean refreshingContext = new Boolean(false);
	
	/**
	 * Static variable holding whether or not to use the system classloader. By default this is
	 * false so the openmrs classloader is used instead
	 */
	private boolean useSystemClassLoader = false;
	
	// Cached service objects
	@SuppressWarnings("unchecked")
	Map<Class, Object> services = new HashMap<Class, Object>();
	
	// Advisors added to services by this service
	@SuppressWarnings("unchecked")
	Map<Class, Set<Advisor>> addedAdvisors = new HashMap<Class, Set<Advisor>>();
	
	// Advice added to services by this service
	@SuppressWarnings("unchecked")
	Map<Class, Set<Advice>> addedAdvice = new HashMap<Class, Set<Advice>>();
	
	/**
	 * The default constructor is private so as to keep only one instance per java vm.
	 * 
	 * @see ServiceContext#getInstance()
	 */
	private ServiceContext() {
		log.debug("Instantiating service context");
	}
	
	/**
	 * There should only be one ServiceContext per openmrs (java virtual machine). This method
	 * should be used when wanting to fetch the service context Note: The ServiceContext shouldn't
	 * be used independently. All calls should go through the Context
	 * 
	 * @return This VM's current ServiceContext.
	 * @see org.openmrs.api.context.Context
	 */
	public static ServiceContext getInstance() {
		if (instance == null)
			instance = new ServiceContext();
		
		return instance;
	}
	
	/**
	 * Null out the current instance of the ServiceContext. This should be used when modules are
	 * refreshing (being added/removed) and/or openmrs is shutting down
	 */
	@SuppressWarnings("unchecked")
	public static void destroyInstance() {
		if (instance != null && instance.services != null) {
			if (log.isDebugEnabled()) {
				for (Map.Entry<Class, Object> entry : instance.services.entrySet()) {
					log.debug("Service - " + entry.getKey().getName() + ":" + entry.getValue());
				}
			}
			
			// Remove advice and advisors that this service added
			for (Class serviceClass : instance.services.keySet()) {
				instance.removeAddedAOP(serviceClass);
			}
			
			if (instance.services != null) {
				instance.services.clear();
				instance.services = null;
			}
			
			if (instance.addedAdvisors != null) {
				instance.addedAdvisors.clear();
				instance.addedAdvisors = null;
			}
			
			if (instance.addedAdvice != null) {
				instance.addedAdvice.clear();
				instance.addedAdvice = null;
			}
		}
		
		if (log.isDebugEnabled())
			log.debug("Destroying ServiceContext instance: " + instance);
		
		instance = null;
	}
	
	/**
	 * @return encounter-related services
	 */
	public EncounterService getEncounterService() {
		return getService(EncounterService.class);
	}
	
	/**
	 * @return location services
	 */
	public LocationService getLocationService() {
		return getService(LocationService.class);
	}
	
	/**
	 * @return observation services
	 */
	public ObsService getObsService() {
		return getService(ObsService.class);
	}
	
	/**
	 * @return patientset-related services
	 */
	public PatientSetService getPatientSetService() {
		return getService(PatientSetService.class);
	}
	
	/**
	 * @return cohort related service
	 */
	public CohortService getCohortService() {
		return getService(CohortService.class);
	}
	
	/**
	 * @param cs cohort related service
	 */
	public void setCohortService(CohortService cs) {
		setService(CohortService.class, cs);
	}
	
	/**
	 * @return order service
	 */
	public OrderService getOrderService() {
		return getService(OrderService.class);
	}
	
	/**
	 * @return form service
	 */
	public FormService getFormService() {
		return getService(FormService.class);
	}
	
	/**
	 * @return report object service
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public ReportObjectService getReportObjectService() {
		return getService(ReportObjectService.class);
	}
	
	/**
	 * @return serialization service
	 */
	public SerializationService getSerializationService() {
		return getService(SerializationService.class);
	}
	
	/**
	 * @return report service
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public ReportService getReportService() {
		return getService(ReportService.class);
	}
	
	/**
	 * @return admin-related services
	 */
	public AdministrationService getAdministrationService() {
		return getService(AdministrationService.class);
	}
	
	/**
	 * @return programWorkflowService
	 */
	public ProgramWorkflowService getProgramWorkflowService() {
		return getService(ProgramWorkflowService.class);
	}
	
	/**
	 * @return ardenService
	 */
	public ArdenService getArdenService() {
		return getService(ArdenService.class);
	}
	
	/**
	 * @return logicService
	 */
	public LogicService getLogicService() {
		return getService(LogicService.class);
	}
	
	/**
	 * @return scheduler service
	 */
	public SchedulerService getSchedulerService() {
		return getService(SchedulerService.class);
	}
	
	/**
	 * Set the scheduler service.
	 * 
	 * @param schedulerService
	 */
	public void setSchedulerService(SchedulerService schedulerService) {
		setService(SchedulerService.class, schedulerService);
	}
	
	/**
	 * @return alert service
	 */
	public AlertService getAlertService() {
		return getService(AlertService.class);
	}
	
	/**
	 * @param alertService
	 */
	public void setAlertService(AlertService alertService) {
		setService(AlertService.class, alertService);
	}
	
	/**
	 * @param programWorkflowService
	 */
	public void setProgramWorkflowService(ProgramWorkflowService programWorkflowService) {
		setService(ProgramWorkflowService.class, programWorkflowService);
	}
	
	/**
	 * @param ardenService
	 */
	public void setArdenService(ArdenService ardenService) {
		setService(ArdenService.class, ardenService);
	}
	
	/**
	 * @param logicService
	 */
	public void setLogicService(LogicService logicService) {
		setService(LogicService.class, logicService);
	}
	
	/**
	 * @return message service
	 */
	public MessageService getMessageService() {
		return getService(MessageService.class);
	}
	
	/**
	 * Sets the message service.
	 * 
	 * @param messageService
	 */
	public void setMessageService(MessageService messageService) {
		setService(MessageService.class, messageService);
	}
	
	/**
	 * @return the hl7Service
	 */
	public HL7Service getHL7Service() {
		return getService(HL7Service.class);
	}
	
	/**
	 * @param hl7Service the hl7Service to set
	 */
	// TODO spring is demanding that this be hl7Service:setHl7Service and not hL7Service:setHL7Service. why?
	public void setHl7Service(HL7Service hl7Service) {
		setService(HL7Service.class, hl7Service);
	}
	
	/**
	 * @param administrationService the administrationService to set
	 */
	public void setAdministrationService(AdministrationService administrationService) {
		setService(AdministrationService.class, administrationService);
	}
	
	/**
	 * @param encounterService the encounterService to set
	 */
	public void setEncounterService(EncounterService encounterService) {
		setService(EncounterService.class, encounterService);
	}
	
	/**
	 * @param locationService the LocationService to set
	 */
	public void setLocationService(LocationService locationService) {
		setService(LocationService.class, locationService);
	}
	
	/**
	 * @param formService the formService to set
	 */
	public void setFormService(FormService formService) {
		setService(FormService.class, formService);
	}
	
	/**
	 * @param obsService the obsService to set
	 */
	public void setObsService(ObsService obsService) {
		setService(ObsService.class, obsService);
	}
	
	/**
	 * @param orderService the orderService to set
	 */
	public void setOrderService(OrderService orderService) {
		setService(OrderService.class, orderService);
	}
	
	/**
	 * @param patientSetService the patientSetService to set
	 */
	public void setPatientSetService(PatientSetService patientSetService) {
		setService(PatientSetService.class, patientSetService);
	}
	
	/**
	 * @param reportObjectService the reportObjectService to set
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public void setReportObjectService(ReportObjectService reportObjectService) {
		setService(ReportObjectService.class, reportObjectService);
	}
	
	/**
	 * @param reportService
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public void setReportService(ReportService reportService) {
		setService(ReportService.class, reportService);
	}
	
	/**
	 * @param serializationService
	 */
	public void setSerializationService(SerializationService serializationService) {
		setService(SerializationService.class, serializationService);
	}
	
	/**
	 * @param dataSetService
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public void setDataSetService(DataSetService dataSetService) {
		setService(DataSetService.class, dataSetService);
	}
	
	/**
	 * @return the DataSetService
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public DataSetService getDataSetService() {
		return getService(DataSetService.class);
	}
	
	/**
	 * @return patient related services
	 */
	public PatientService getPatientService() {
		return getService(PatientService.class);
	}
	
	/**
	 * @param patientService the patientService to set
	 */
	public void setPatientService(PatientService patientService) {
		setService(PatientService.class, patientService);
	}
	
	/**
	 * @return person related services
	 */
	public PersonService getPersonService() {
		return getService(PersonService.class);
	}
	
	/**
	 * @param personService the personService to set
	 */
	public void setPersonService(PersonService personService) {
		setService(PersonService.class, personService);
	}
	
	/**
	 * @return concept related services
	 */
	public ConceptService getConceptService() {
		return getService(ConceptService.class);
	}
	
	/**
	 * @param conceptService the conceptService to set
	 */
	public void setConceptService(ConceptService conceptService) {
		setService(ConceptService.class, conceptService);
	}
	
	/**
	 * @return user-related services
	 */
	public UserService getUserService() {
		return getService(UserService.class);
	}
	
	/**
	 * @param userService the userService to set
	 */
	public void setUserService(UserService userService) {
		setService(UserService.class, userService);
	}
	
	/**
	 * Gets the MessageSourceService used in the context.
	 * 
	 * @return MessageSourceService
	 */
	public MessageSourceService getMessageSourceService() {
		return getService(MessageSourceService.class);
	}
	
	/**
	 * Sets the MessageSourceService used in the context.
	 * 
	 * @param messageSourceService the MessageSourceService to use
	 */
	public void setMessageSourceService(MessageSourceService messageSourceService) {
		setService(MessageSourceService.class, messageSourceService);
	}
	
	/**
	 * Gets the ActiveListService used in the context.
	 * 
	 * @return ActiveListService
	 */
	public ActiveListService getActiveListService() {
		return getService(ActiveListService.class);
	}
	
	/**
	 * Sets the ActiveListService used in the context
	 */
	public void setActiveListService(ActiveListService activeListService) {
		setService(ActiveListService.class, activeListService);
	}
	
	/**
	 * @param cls
	 * @param advisor
	 */
	@SuppressWarnings("unchecked")
	public void addAdvisor(Class cls, Advisor advisor) {
		Advised advisedService = (Advised) services.get(cls);
		advisedService.addAdvisor(advisor);
		if (addedAdvice.get(cls) == null)
			addedAdvisors.put(cls, new HashSet<Advisor>());
		getAddedAdvisors(cls).add(advisor);
	}
	
	/**
	 * @param cls
	 * @param advice
	 */
	@SuppressWarnings("unchecked")
	public void addAdvice(Class cls, Advice advice) {
		Advised advisedService = (Advised) services.get(cls);
		advisedService.addAdvice(advice);
		if (addedAdvice.get(cls) == null)
			addedAdvice.put(cls, new HashSet<Advice>());
		getAddedAdvice(cls).add(advice);
	}
	
	/**
	 * @param cls
	 * @param advisor
	 */
	@SuppressWarnings("unchecked")<commit_msg>for TRUNK-1604 fixing ServiceContext to not load advice or advisors twice<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.api.context;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aopalliance.aop.Advice;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.api.APIException;
import org.openmrs.api.ActiveListService;
import org.openmrs.api.AdministrationService;
import org.openmrs.api.CohortService;
import org.openmrs.api.ConceptService;
import org.openmrs.api.DataSetService;
import org.openmrs.api.EncounterService;
import org.openmrs.api.FormService;
import org.openmrs.api.LocationService;
import org.openmrs.api.ObsService;
import org.openmrs.api.OrderService;
import org.openmrs.api.PatientService;
import org.openmrs.api.PatientSetService;
import org.openmrs.api.PersonService;
import org.openmrs.api.ProgramWorkflowService;
import org.openmrs.api.ReportService;
import org.openmrs.api.SerializationService;
import org.openmrs.api.UserService;
import org.openmrs.arden.ArdenService;
import org.openmrs.hl7.HL7Service;
import org.openmrs.logic.LogicService;
import org.openmrs.messagesource.MessageSourceService;
import org.openmrs.notification.AlertService;
import org.openmrs.notification.MessageService;
import org.openmrs.reporting.ReportObjectService;
import org.openmrs.scheduler.SchedulerService;
import org.openmrs.util.OpenmrsClassLoader;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * Represents an OpenMRS <code>Service Context</code>, which returns the services represented
 * throughout the system. <br/>
 * <br/>
 * This class should not be access directly, but rather used through the <code>Context</code> class. <br/>
 * <br/>
 * This class is essentially static and only one instance is kept because this is fairly
 * heavy-weight. Spring takes care of filling in the actual service implementations via dependency
 * injection. See the /metadata/api/spring/applicationContext-service.xml file. <br/>
 * <br/>
 * Module services are also accessed through this class. See {@link #getService(Class)}
 * 
 * @see org.openmrs.api.context.Context
 */
public class ServiceContext implements ApplicationContextAware {
	
	private static final Log log = LogFactory.getLog(ServiceContext.class);
	
	private static ServiceContext instance;
	
	private ApplicationContext applicationContext;
	
	private Boolean refreshingContext = new Boolean(false);
	
	/**
	 * Static variable holding whether or not to use the system classloader. By default this is
	 * false so the openmrs classloader is used instead
	 */
	private boolean useSystemClassLoader = false;
	
	// Cached service objects
	@SuppressWarnings("unchecked")
	Map<Class, Object> services = new HashMap<Class, Object>();
	
	// Advisors added to services by this service
	@SuppressWarnings("unchecked")
	Map<Class, Set<Advisor>> addedAdvisors = new HashMap<Class, Set<Advisor>>();
	
	// Advice added to services by this service
	@SuppressWarnings("unchecked")
	Map<Class, Set<Advice>> addedAdvice = new HashMap<Class, Set<Advice>>();
	
	/**
	 * The default constructor is private so as to keep only one instance per java vm.
	 * 
	 * @see ServiceContext#getInstance()
	 */
	private ServiceContext() {
		log.debug("Instantiating service context");
	}
	
	/**
	 * There should only be one ServiceContext per openmrs (java virtual machine). This method
	 * should be used when wanting to fetch the service context Note: The ServiceContext shouldn't
	 * be used independently. All calls should go through the Context
	 * 
	 * @return This VM's current ServiceContext.
	 * @see org.openmrs.api.context.Context
	 */
	public static ServiceContext getInstance() {
		if (instance == null)
			instance = new ServiceContext();
		
		return instance;
	}
	
	/**
	 * Null out the current instance of the ServiceContext. This should be used when modules are
	 * refreshing (being added/removed) and/or openmrs is shutting down
	 */
	@SuppressWarnings("unchecked")
	public static void destroyInstance() {
		if (instance != null && instance.services != null) {
			if (log.isDebugEnabled()) {
				for (Map.Entry<Class, Object> entry : instance.services.entrySet()) {
					log.debug("Service - " + entry.getKey().getName() + ":" + entry.getValue());
				}
			}
			
			// Remove advice and advisors that this service added
			for (Class serviceClass : instance.services.keySet()) {
				instance.removeAddedAOP(serviceClass);
			}
			
			if (instance.services != null) {
				instance.services.clear();
				instance.services = null;
			}
			
			if (instance.addedAdvisors != null) {
				instance.addedAdvisors.clear();
				instance.addedAdvisors = null;
			}
			
			if (instance.addedAdvice != null) {
				instance.addedAdvice.clear();
				instance.addedAdvice = null;
			}
		}
		
		if (log.isDebugEnabled())
			log.debug("Destroying ServiceContext instance: " + instance);
		
		instance = null;
	}
	
	/**
	 * @return encounter-related services
	 */
	public EncounterService getEncounterService() {
		return getService(EncounterService.class);
	}
	
	/**
	 * @return location services
	 */
	public LocationService getLocationService() {
		return getService(LocationService.class);
	}
	
	/**
	 * @return observation services
	 */
	public ObsService getObsService() {
		return getService(ObsService.class);
	}
	
	/**
	 * @return patientset-related services
	 */
	public PatientSetService getPatientSetService() {
		return getService(PatientSetService.class);
	}
	
	/**
	 * @return cohort related service
	 */
	public CohortService getCohortService() {
		return getService(CohortService.class);
	}
	
	/**
	 * @param cs cohort related service
	 */
	public void setCohortService(CohortService cs) {
		setService(CohortService.class, cs);
	}
	
	/**
	 * @return order service
	 */
	public OrderService getOrderService() {
		return getService(OrderService.class);
	}
	
	/**
	 * @return form service
	 */
	public FormService getFormService() {
		return getService(FormService.class);
	}
	
	/**
	 * @return report object service
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public ReportObjectService getReportObjectService() {
		return getService(ReportObjectService.class);
	}
	
	/**
	 * @return serialization service
	 */
	public SerializationService getSerializationService() {
		return getService(SerializationService.class);
	}
	
	/**
	 * @return report service
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public ReportService getReportService() {
		return getService(ReportService.class);
	}
	
	/**
	 * @return admin-related services
	 */
	public AdministrationService getAdministrationService() {
		return getService(AdministrationService.class);
	}
	
	/**
	 * @return programWorkflowService
	 */
	public ProgramWorkflowService getProgramWorkflowService() {
		return getService(ProgramWorkflowService.class);
	}
	
	/**
	 * @return ardenService
	 */
	public ArdenService getArdenService() {
		return getService(ArdenService.class);
	}
	
	/**
	 * @return logicService
	 */
	public LogicService getLogicService() {
		return getService(LogicService.class);
	}
	
	/**
	 * @return scheduler service
	 */
	public SchedulerService getSchedulerService() {
		return getService(SchedulerService.class);
	}
	
	/**
	 * Set the scheduler service.
	 * 
	 * @param schedulerService
	 */
	public void setSchedulerService(SchedulerService schedulerService) {
		setService(SchedulerService.class, schedulerService);
	}
	
	/**
	 * @return alert service
	 */
	public AlertService getAlertService() {
		return getService(AlertService.class);
	}
	
	/**
	 * @param alertService
	 */
	public void setAlertService(AlertService alertService) {
		setService(AlertService.class, alertService);
	}
	
	/**
	 * @param programWorkflowService
	 */
	public void setProgramWorkflowService(ProgramWorkflowService programWorkflowService) {
		setService(ProgramWorkflowService.class, programWorkflowService);
	}
	
	/**
	 * @param ardenService
	 */
	public void setArdenService(ArdenService ardenService) {
		setService(ArdenService.class, ardenService);
	}
	
	/**
	 * @param logicService
	 */
	public void setLogicService(LogicService logicService) {
		setService(LogicService.class, logicService);
	}
	
	/**
	 * @return message service
	 */
	public MessageService getMessageService() {
		return getService(MessageService.class);
	}
	
	/**
	 * Sets the message service.
	 * 
	 * @param messageService
	 */
	public void setMessageService(MessageService messageService) {
		setService(MessageService.class, messageService);
	}
	
	/**
	 * @return the hl7Service
	 */
	public HL7Service getHL7Service() {
		return getService(HL7Service.class);
	}
	
	/**
	 * @param hl7Service the hl7Service to set
	 */
	// TODO spring is demanding that this be hl7Service:setHl7Service and not hL7Service:setHL7Service. why?
	public void setHl7Service(HL7Service hl7Service) {
		setService(HL7Service.class, hl7Service);
	}
	
	/**
	 * @param administrationService the administrationService to set
	 */
	public void setAdministrationService(AdministrationService administrationService) {
		setService(AdministrationService.class, administrationService);
	}
	
	/**
	 * @param encounterService the encounterService to set
	 */
	public void setEncounterService(EncounterService encounterService) {
		setService(EncounterService.class, encounterService);
	}
	
	/**
	 * @param locationService the LocationService to set
	 */
	public void setLocationService(LocationService locationService) {
		setService(LocationService.class, locationService);
	}
	
	/**
	 * @param formService the formService to set
	 */
	public void setFormService(FormService formService) {
		setService(FormService.class, formService);
	}
	
	/**
	 * @param obsService the obsService to set
	 */
	public void setObsService(ObsService obsService) {
		setService(ObsService.class, obsService);
	}
	
	/**
	 * @param orderService the orderService to set
	 */
	public void setOrderService(OrderService orderService) {
		setService(OrderService.class, orderService);
	}
	
	/**
	 * @param patientSetService the patientSetService to set
	 */
	public void setPatientSetService(PatientSetService patientSetService) {
		setService(PatientSetService.class, patientSetService);
	}
	
	/**
	 * @param reportObjectService the reportObjectService to set
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public void setReportObjectService(ReportObjectService reportObjectService) {
		setService(ReportObjectService.class, reportObjectService);
	}
	
	/**
	 * @param reportService
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public void setReportService(ReportService reportService) {
		setService(ReportService.class, reportService);
	}
	
	/**
	 * @param serializationService
	 */
	public void setSerializationService(SerializationService serializationService) {
		setService(SerializationService.class, serializationService);
	}
	
	/**
	 * @param dataSetService
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public void setDataSetService(DataSetService dataSetService) {
		setService(DataSetService.class, dataSetService);
	}
	
	/**
	 * @return the DataSetService
	 * @deprecated see reportingcompatibility module
	 */
	@Deprecated
	public DataSetService getDataSetService() {
		return getService(DataSetService.class);
	}
	
	/**
	 * @return patient related services
	 */
	public PatientService getPatientService() {
		return getService(PatientService.class);
	}
	
	/**
	 * @param patientService the patientService to set
	 */
	public void setPatientService(PatientService patientService) {
		setService(PatientService.class, patientService);
	}
	
	/**
	 * @return person related services
	 */
	public PersonService getPersonService() {
		return getService(PersonService.class);
	}
	
	/**
	 * @param personService the personService to set
	 */
	public void setPersonService(PersonService personService) {
		setService(PersonService.class, personService);
	}
	
	/**
	 * @return concept related services
	 */
	public ConceptService getConceptService() {
		return getService(ConceptService.class);
	}
	
	/**
	 * @param conceptService the conceptService to set
	 */
	public void setConceptService(ConceptService conceptService) {
		setService(ConceptService.class, conceptService);
	}
	
	/**
	 * @return user-related services
	 */
	public UserService getUserService() {
		return getService(UserService.class);
	}
	
	/**
	 * @param userService the userService to set
	 */
	public void setUserService(UserService userService) {
		setService(UserService.class, userService);
	}
	
	/**
	 * Gets the MessageSourceService used in the context.
	 * 
	 * @return MessageSourceService
	 */
	public MessageSourceService getMessageSourceService() {
		return getService(MessageSourceService.class);
	}
	
	/**
	 * Sets the MessageSourceService used in the context.
	 * 
	 * @param messageSourceService the MessageSourceService to use
	 */
	public void setMessageSourceService(MessageSourceService messageSourceService) {
		setService(MessageSourceService.class, messageSourceService);
	}
	
	/**
	 * Gets the ActiveListService used in the context.
	 * 
	 * @return ActiveListService
	 */
	public ActiveListService getActiveListService() {
		return getService(ActiveListService.class);
	}
	
	/**
	 * Sets the ActiveListService used in the context
	 */
	public void setActiveListService(ActiveListService activeListService) {
		setService(ActiveListService.class, activeListService);
	}
	
	/**
	 * @param cls
	 * @param advisor
	 */
	@SuppressWarnings("unchecked")
	public void addAdvisor(Class cls, Advisor advisor) {
		Advised advisedService = (Advised) services.get(cls);
		if (advisedService.indexOf(advisor) < 0)
			advisedService.addAdvisor(advisor);
		if (addedAdvisors.get(cls) == null)
			addedAdvisors.put(cls, new HashSet<Advisor>());
		getAddedAdvisors(cls).add(advisor);
	}
	
	/**
	 * @param cls
	 * @param advice
	 */
	@SuppressWarnings("unchecked")
	public void addAdvice(Class cls, Advice advice) {
		Advised advisedService = (Advised) services.get(cls);
		if (advisedService.indexOf(advice) < 0)
			advisedService.addAdvice(advice);
		if (addedAdvice.get(cls) == null)
			addedAdvice.put(cls, new HashSet<Advice>());
		getAddedAdvice(cls).add(advice);
	}
	
	/**
	 * @param cls
	 * @param advisor
	 */
	@SuppressWarnings("unchecked")
{'fraction_non_alphanumeric': 0.1000561185752484, 'fraction_numerical': 0.0014524807711352459, 'mean_word_length': 4.482084690553746, 'pattern_counts': {'":': 2, '<': 51, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '5445681', 'n_tokens_mistral': 9356, 'n_tokens_neox': 8450, 'n_words': 2175}