Java tutorial
/** * 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.module.metadatamapping.api.impl; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Concept; import org.openmrs.ConceptMap; import org.openmrs.ConceptSource; import org.openmrs.GlobalProperty; import org.openmrs.ImplementationId; import org.openmrs.OpenmrsMetadata; import org.openmrs.api.APIException; import org.openmrs.api.AdministrationService; import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.api.impl.BaseOpenmrsService; import org.openmrs.module.metadatamapping.MetadataMapping; import org.openmrs.module.metadatamapping.MetadataSource; import org.openmrs.module.metadatamapping.MetadataTermMapping; import org.openmrs.module.metadatamapping.api.MetadataMappingService; import org.openmrs.module.metadatamapping.api.MetadataSourceSearchCriteria; import org.openmrs.module.metadatamapping.api.MetadataSourceSearchCriteriaBuilder; import org.openmrs.module.metadatamapping.api.MetadataTermMappingSearchCriteria; import org.openmrs.module.metadatamapping.api.MetadataTermMappingSearchCriteriaBuilder; import org.openmrs.module.metadatamapping.api.db.MetadataMappingDAO; import org.openmrs.module.metadatamapping.api.wrapper.ConceptAdapter; import org.springframework.transaction.annotation.Transactional; /** * The service implementation. */ public class MetadataMappingServiceImpl extends BaseOpenmrsService implements MetadataMappingService { protected final Log log = LogFactory.getLog(getClass()); private AdministrationService adminService; private ConceptService conceptService; private MetadataMappingDAO dao; private ConceptAdapter conceptAdapter; private int batchSize = 1000; public void setBatchSize(int batchSize) { this.batchSize = batchSize; } public void setAdminService(AdministrationService adminService) { this.adminService = adminService; } public void setConceptService(ConceptService conceptService) { this.conceptService = conceptService; } public void setConceptAdapter(ConceptAdapter conceptAdapter) { this.conceptAdapter = conceptAdapter; } public void setDao(MetadataMappingDAO dao) { this.dao = dao; } @Override @Transactional public ConceptSource createLocalConceptSourceFromImplementationId() { ImplementationId implementationId = adminService.getImplementationId(); if (implementationId == null) { throw new APIException("Implementation id is not set"); } final ConceptSource source = new ConceptSource(); source.setName(implementationId.getImplementationId() + MetadataMapping.LOCAL_SOURCE_NAME_POSTFIX); source.setDescription( MetadataMapping.LOCAL_SOURCE_DESCRIPTION_PREFIX + implementationId.getImplementationId()); conceptService.saveConceptSource(source); setLocalConceptSource(source); return source; } @Override @Transactional(readOnly = true) public ConceptSource getLocalConceptSource() { final String sourceUuid = adminService.getGlobalProperty(MetadataMapping.GP_LOCAL_SOURCE_UUID, ""); if (StringUtils.isEmpty(sourceUuid)) { throw new APIException("Local concept source is not set in the " + MetadataMapping.GP_LOCAL_SOURCE_UUID + " global property. Call createLocalConceptSourceFromImplementationId to have it set automatically."); } else { final ConceptSource source = conceptService.getConceptSourceByUuid(sourceUuid); if (source == null) { throw new APIException("Local concept source [" + sourceUuid + "] set in the " + MetadataMapping.GP_LOCAL_SOURCE_UUID + " global property does not exist. Set the global property to " + "an existing concept source."); } return source; } } @Override @Transactional(readOnly = true) public boolean isLocalConceptSourceConfigured() { final String sourceUuid = adminService.getGlobalProperty(MetadataMapping.GP_LOCAL_SOURCE_UUID, ""); if (!StringUtils.isBlank(sourceUuid)) { final ConceptSource source = conceptService.getConceptSourceByUuid(sourceUuid); return (source != null); } else { return false; } } /** * @see org.openmrs.module.metadatamapping.api.MetadataMappingService#isAddLocalMappingToConceptOnExport() */ @Override public boolean isAddLocalMappingToConceptOnExport() { String addLocalMappings = adminService.getGlobalProperty(MetadataMapping.GP_ADD_LOCAL_MAPPINGS, ""); return Boolean.valueOf(addLocalMappings); } @Override @Transactional public void addLocalMappingToConcept(final Concept concept) { if (concept.getId() == null) { return; } final ConceptSource localConceptSource = getLocalConceptSource(); if (!conceptAdapter.hasMappingToSource(concept, localConceptSource)) { conceptAdapter.addMapping(concept, localConceptSource, concept.getId().toString()); } } @Override @Transactional public void markLocalMappingRetiredInConcept(final Concept concept) { if (concept.getId() == null) { return; } final ConceptSource localConceptSource = getLocalConceptSource(); conceptAdapter.retireMapping(concept, localConceptSource, concept.getId().toString()); } @Override @Transactional public void markLocalMappingUnretiredInConcept(final Concept concept) { if (concept.getId() == null) { return; } final ConceptSource localConceptSource = getLocalConceptSource(); conceptAdapter.unretireMapping(concept, localConceptSource, concept.getId().toString()); } @Override @Transactional public void purgeLocalMappingInConcept(final Concept concept) { if (concept.getId() == null) { return; } final ConceptSource localConceptSource = getLocalConceptSource(); conceptAdapter.purgeMapping(concept, localConceptSource, concept.getId().toString()); } @Override @Transactional public void addLocalMappingToAllConcepts() { int position = 0; List<Concept> concepts = dao.getConcepts(position, batchSize); while (true) { for (Concept concept : concepts) { addLocalMappingToConcept(concept); if (concept.isRetired()) { markLocalMappingRetiredInConcept(concept); } } if (concepts.size() == batchSize) { position += batchSize; concepts = dao.getConcepts(position, batchSize); } else { break; } } } @Override @Transactional(readOnly = true) public Set<ConceptSource> getSubscribedConceptSources() { final String sourceUuidsList = adminService.getGlobalProperty(MetadataMapping.GP_SUBSCRIBED_TO_SOURCE_UUIDS, ""); if (StringUtils.isBlank(sourceUuidsList)) { return Collections.emptySet(); } final String[] sourceUuids = sourceUuidsList.split(","); final Set<ConceptSource> subscribedConceptSources = new HashSet<ConceptSource>(); for (String sourceUuid : sourceUuids) { sourceUuid = sourceUuid.trim(); final ConceptSource source = conceptService.getConceptSourceByUuid(sourceUuid); if (source != null) { subscribedConceptSources.add(source); } } return Collections.unmodifiableSet(subscribedConceptSources); } @Transactional @Override public boolean addSubscribedConceptSource(ConceptSource conceptSource) { Set<ConceptSource> subscribedConceptSources = new HashSet<ConceptSource>(getSubscribedConceptSources()); if (!subscribedConceptSources.add(conceptSource)) { return false; } updateSubscribedConceptSourcesGlobalProperty(subscribedConceptSources); return true; } @Transactional @Override public boolean removeSubscribedConceptSource(ConceptSource conceptSource) { Set<ConceptSource> subscribedConceptSources = new HashSet<ConceptSource>(getSubscribedConceptSources()); if (!subscribedConceptSources.remove(conceptSource)) { return false; } updateSubscribedConceptSourcesGlobalProperty(subscribedConceptSources); return true; } private void updateSubscribedConceptSourcesGlobalProperty(Set<ConceptSource> subscribedConceptSources) { GlobalProperty sourceUuidsGP = adminService .getGlobalPropertyObject(MetadataMapping.GP_SUBSCRIBED_TO_SOURCE_UUIDS); if (sourceUuidsGP == null) { sourceUuidsGP = new GlobalProperty(MetadataMapping.GP_SUBSCRIBED_TO_SOURCE_UUIDS, ""); } Set<String> sourceUuids = new HashSet<String>(); for (ConceptSource subscribedConceptSource : subscribedConceptSources) { sourceUuids.add(subscribedConceptSource.getUuid()); } sourceUuidsGP.setPropertyValue(StringUtils.join(sourceUuids, ",")); adminService.saveGlobalProperty(sourceUuidsGP); } @Override public boolean isLocalConcept(final Concept concept) { final Set<ConceptSource> subscribedConceptSources = getSubscribedConceptSources(); if (concept.getConceptMappings() != null) { for (ConceptMap map : concept.getConceptMappings()) { if (subscribedConceptSources.contains(map.getConceptReferenceTerm().getConceptSource())) { return false; } } } return true; } @Override public Concept getConcept(final String mapping) { if (StringUtils.isBlank(mapping)) { throw new IllegalArgumentException("Mapping must not be blank"); } final String[] split = mapping.split(":"); if (split.length == 1) { try { final Integer id = Integer.valueOf(split[0]); return getConcept(id); } catch (NumberFormatException e) { throw new IllegalArgumentException( "Mapping '" + mapping + "' has format 'id'. The id '" + split[0] + "' must be an integer.", e); } } else if (split.length == 2) { final String source = split[0]; final String code = split[1]; try { Integer.parseInt(code); } catch (NumberFormatException e) { throw new IllegalArgumentException("Mapping '" + mapping + "' has format 'source:id'. The id '" + split[0] + "' must be an integer.", e); } return Context.getConceptService().getConceptByMapping(code, source); } else { throw new IllegalArgumentException("Mapping '" + mapping + "' must contain only one ':'"); } } @Override public Concept getConcept(final Integer id) { return conceptService.getConcept(id); } @Override public void setLocalConceptSource(ConceptSource conceptSource) { adminService.saveGlobalProperty( new GlobalProperty(MetadataMapping.GP_LOCAL_SOURCE_UUID, conceptSource.getUuid())); } @Override @Transactional public MetadataSource saveMetadataSource(MetadataSource metadataSource) { return dao.saveMetadataSource(metadataSource); } @Override @Transactional(readOnly = true) public List<MetadataSource> getMetadataSources(boolean includeRetired) { return dao.getMetadataSources( new MetadataSourceSearchCriteriaBuilder().setIncludeAll(includeRetired).build()); } @Override @Transactional(readOnly = true) public List<MetadataSource> getMetadataSources(MetadataSourceSearchCriteria searchCriteria) { return dao.getMetadataSources(searchCriteria); } @Override @Transactional(readOnly = true) public MetadataSource getMetadataSource(Integer metadataSourceId) { return dao.getMetadataSource(metadataSourceId); } @Override @Transactional(readOnly = true) public MetadataSource getMetadataSourceByUuid(String metadataSourceUuid) { return dao.getByUuid(MetadataSource.class, metadataSourceUuid); } @Override @Transactional(readOnly = true) public MetadataSource getMetadataSourceByName(String metadataSourceName) { return dao.getMetadataSourceByName(metadataSourceName); } @Override @Transactional public MetadataSource retireMetadataSource(MetadataSource metadataSource, String reason) { // Required values are already set by the injected BaseRetireHandler. return dao.saveMetadataSource(metadataSource); } @Override @Transactional public MetadataTermMapping saveMetadataTermMapping(MetadataTermMapping metadataTermMapping) { return dao.saveMetadataTermMapping(metadataTermMapping); } @Override @Transactional public Collection<MetadataTermMapping> saveMetadataTermMappings( Collection<MetadataTermMapping> metadataTermMappings) { return dao.saveMetadataTermMappings(metadataTermMappings); } @Override @Transactional(readOnly = true) public MetadataTermMapping getMetadataTermMapping(Integer metadataTermMappingId) { return dao.getMetadataTermMapping(metadataTermMappingId); } @Override @Transactional(readOnly = true) public MetadataTermMapping getMetadataTermMappingByUuid(String metadataTermMappingUuid) { return dao.getByUuid(MetadataTermMapping.class, metadataTermMappingUuid); } @Override @Transactional(readOnly = true) public List<MetadataTermMapping> getMetadataTermMappings(MetadataTermMappingSearchCriteria searchCriteria) { return dao.getMetadataTermMappings(searchCriteria); } @Override @Transactional(readOnly = true) public List<MetadataTermMapping> getMetadataTermMappings(OpenmrsMetadata referredObject) { MetadataTermMappingSearchCriteria searchCriteria = new MetadataTermMappingSearchCriteriaBuilder() .setIncludeAll(false).setReferredObject(referredObject).build(); return dao.getMetadataTermMappings(searchCriteria); } @Override @Transactional public MetadataTermMapping retireMetadataTermMapping(MetadataTermMapping metadataTermMapping, String reason) { // Required values are already set by the injected BaseRetireHandler. return dao.saveMetadataTermMapping(metadataTermMapping); } @Override @Transactional(readOnly = true) public MetadataTermMapping getMetadataTermMapping(MetadataSource metadataSource, String metadataTermCode) { return dao.getMetadataTermMapping(metadataSource, metadataTermCode); } @Override @Transactional(readOnly = true) public List<MetadataTermMapping> getMetadataTermMappings(MetadataSource metadataSource) { MetadataTermMappingSearchCriteria searchCriteria = new MetadataTermMappingSearchCriteriaBuilder() .setIncludeAll(false).setMetadataSource(metadataSource).build(); return dao.getMetadataTermMappings(searchCriteria); } @Override @Transactional(readOnly = true) public <T extends OpenmrsMetadata> T getMetadataItem(Class<T> type, String metadataSourceName, String metadataTermCode) { return dao.getMetadataItem(type, metadataSourceName, metadataTermCode); } @Override @Transactional(readOnly = true) public <T extends OpenmrsMetadata> List<T> getMetadataItems(Class<T> type, String metadataSourceName) { return dao.getMetadataItems(type, metadataSourceName); } }