Skip to content

Instantly share code, notes, and snippets.

@kaweesi
Created April 19, 2017 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaweesi/4d42bc8921205e83ae7a2d35372af75c to your computer and use it in GitHub Desktop.
Save kaweesi/4d42bc8921205e83ae7a2d35372af75c to your computer and use it in GitHub Desktop.
/**
* 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.dhisconnector.api.impl;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.openmrs.api.context.Context;
import org.openmrs.api.impl.BaseOpenmrsService;
import org.openmrs.module.dhisconnector.Configurations;
import org.openmrs.module.dhisconnector.adx.AdxDataValue;
import org.openmrs.module.dhisconnector.adx.AdxDataValueGroup;
import org.openmrs.module.dhisconnector.adx.AdxDataValueGroupPeriod;
import org.openmrs.module.dhisconnector.adx.AdxDataValueSet;
import org.openmrs.module.dhisconnector.adx.AdxObjectFactory;
import org.openmrs.module.dhisconnector.adx.importsummary.ImportSummaries;
import org.openmrs.module.dhisconnector.api.DHISConnectorService;
import org.openmrs.module.dhisconnector.api.model.DHISCategoryCombo;
import org.openmrs.module.dhisconnector.api.model.DHISCategoryOptionCombo;
import org.openmrs.module.dhisconnector.api.model.DHISDataElement;
import org.openmrs.module.dhisconnector.api.model.DHISDataSet;
import org.openmrs.module.dhisconnector.api.model.DHISDataValue;
import org.openmrs.module.dhisconnector.api.model.DHISDataValueSet;
import org.openmrs.module.dhisconnector.api.model.DHISImportSummary;
import org.openmrs.module.dhisconnector.api.model.DHISMapping;
import org.openmrs.module.dhisconnector.api.model.DHISOrganisationUnit;
import org.openmrs.module.reporting.report.definition.PeriodIndicatorReportDefinition;
import org.openmrs.module.reporting.report.definition.ReportDefinition;
import org.openmrs.module.reporting.report.definition.service.ReportDefinitionService;
import org.openmrs.util.OpenmrsUtil;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* It is a default implementation of {@link DHISConnectorService}.
*/
public class DHISConnectorServiceImpl extends BaseOpenmrsService implements DHISConnectorService {
public static final String DHISCONNECTOR_MAPPINGS_FOLDER = File.separator + "dhisconnector" + File.separator
+ "mappings";
public static final String DHISCONNECTOR_DHIS2BACKUP_FOLDER = File.separator + "dhisconnector" + File.separator
+ "dhis2Backup";
public static final String DHISCONNECTOR_TEMP_FOLDER = File.separator + "dhisconnector" + File.separator + "temp";
public static final String DHISCONNECTOR_MAPPING_FILE_SUFFIX = ".mapping.json";
public static final String DHISCONNECTOR_ORGUNIT_RESOURCE = "/api/organisationUnits.json?paging=false&fields=id,name";
public static final String DATAVALUESETS_PATH = "/api/dataValueSets";
public static final String DATASETS_PATH = "/api/dataSets/";
public static final String ORGUNITS_PATH = "/api/organisationUnits/";
public static String JSON_POST_FIX = ".json";
private String DATA_ELEMETS_PATH = "/api/dataElements/";
private String CAT_OPTION_COMBOS_PATH = "/api/categoryOptionCombos/";
public static final String DHISCONNECTOR_DATA_FOLDER = File.separator + "dhisconnector" + File.separator + "data";
private Configurations configs = new Configurations();
private AdxObjectFactory factory = new AdxObjectFactory();
int count = 0;
private String getFromBackUp(String path) {
String backupFilePath = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER + path;
File backupFile = new File(backupFilePath);
if (backupFile.exists()) {
try {
return FileUtils.readFileToString(backupFile);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
return null;
}
private void saveToBackUp(String path, String jsonResponse) {
String backUpDirecoryPath = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER;
File backUpDirecory = new File(backUpDirecoryPath);
if (!backUpDirecory.exists()) {
try {
if (!backUpDirecory.mkdirs()) {
return;
}
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
String directoryStructure = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER
+ path.substring(0, path.lastIndexOf(File.separator));
File directory = new File(directoryStructure);
if (!directory.exists()) {
try {
if (!directory.mkdirs()) {
return;
}
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
try {
PrintWriter enpointBackUp = new PrintWriter(
OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER + path, "utf-8");
enpointBackUp.write(jsonResponse);
enpointBackUp.close();
}
catch (Exception e) {
e.printStackTrace();
return;
}
return;
}
@Override
public String getDataFromDHISEndpoint(String endpoint) {
String url = Context.getAdministrationService().getGlobalProperty("dhisconnector.url");
String user = Context.getAdministrationService().getGlobalProperty("dhisconnector.user");
String pass = Context.getAdministrationService().getGlobalProperty("dhisconnector.pass");
DefaultHttpClient client = null;
String payload = "";
try {
URL dhisURL = new URL(url);
String host = dhisURL.getHost();
int port = dhisURL.getPort();
HttpHost targetHost = new HttpHost(host, port, dhisURL.getProtocol());
client = new DefaultHttpClient();
BasicHttpContext localcontext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(dhisURL.getPath() + endpoint);
Credentials creds = new UsernamePasswordCredentials(user, pass);
Header bs = new BasicScheme().authenticate(creds, httpGet, localcontext);
httpGet.addHeader("Authorization", bs.getValue());
httpGet.addHeader("Content-Type", "application/json");
httpGet.addHeader("Accept", "application/json");
HttpResponse response = client.execute(targetHost, httpGet, localcontext);
HttpEntity entity = response.getEntity();
if (entity != null && response.getStatusLine().getStatusCode() == 200) {
payload = EntityUtils.toString(entity);
saveToBackUp(endpoint, payload);
} else {
payload = getFromBackUp(endpoint);
}
}
catch (Exception ex) {
ex.printStackTrace();
payload = getFromBackUp(endpoint);
}
finally {
if (client != null) {
client.getConnectionManager().shutdown();
}
}
return payload;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private String getCodeFromClazz(Class clazz, String endPoint) {
ObjectMapper mapper = new ObjectMapper();
String jsonResponse = getDataFromDHISEndpoint(endPoint);
String code = null;
try {
if (StringUtils.isNotBlank(jsonResponse)) {
Object obj = mapper.readValue(jsonResponse, clazz);
if (obj instanceof DHISDataSet)
code = ((DHISDataSet) obj).getCode();
else if (obj instanceof DHISOrganisationUnit)
code = ((DHISOrganisationUnit) obj).getCode();
else if (obj instanceof DHISDataElement)
code = ((DHISDataElement) obj).getCode();
else if (obj instanceof DHISCategoryOptionCombo) {
code = ((DHISCategoryOptionCombo) obj).getCode();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return code != null ? code : "";
}
private DHISCategoryOptionCombo getCategoryOptionCombo(String categoryOptionComboId) {
String data = getDataFromDHISEndpoint(CAT_OPTION_COMBOS_PATH + categoryOptionComboId + JSON_POST_FIX);
if (StringUtils.isNotBlank(data)) {
try {
return new ObjectMapper().readValue(data, DHISCategoryOptionCombo.class);
}
catch (JsonParseException e) {
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private DHISCategoryCombo getCategoryComboFromOption(String categoryOptionComboId) {
String data = getDataFromDHISEndpoint(CAT_OPTION_COMBOS_PATH + categoryOptionComboId + JSON_POST_FIX);
DHISCategoryOptionCombo optionCombo;
if (StringUtils.isNotBlank(data)) {
try {
optionCombo = new ObjectMapper().readValue(data, DHISCategoryOptionCombo.class);
if (optionCombo != null)
return optionCombo.getCategoryCombo();
}
catch (JsonParseException e) {
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private AdxDataValueSet convertDHISDataValueSetToAdxDataValueSet(DHISDataValueSet valueSet) {
AdxDataValueSet adx = null;
if (valueSet != null) {
try {
String dataSet = getCodeFromClazz(DHISDataSet.class, DATASETS_PATH + valueSet.getDataSet() + JSON_POST_FIX);
String orgUnit = getCodeFromClazz(DHISOrganisationUnit.class,
ORGUNITS_PATH + valueSet.getOrgUnit() + JSON_POST_FIX);
String period = valueSet.getPeriod();
AdxDataValueGroup group = new AdxDataValueGroup();
XMLGregorianCalendar exported = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(new GregorianCalendar());
AdxDataValueGroupPeriod adxPeriod = new AdxDataValueGroupPeriod(period);
adx = new AdxDataValueSet();
adx.setExported(exported);
group.setOrgUnit(orgUnit);
group.setDataSet(dataSet);
group.setPeriod(adxPeriod);
group.setCompleteDate(adxPeriod.getdHISAdxEndDate());
for (DHISDataValue dv : valueSet.getDataValues()) {
AdxDataValue adxDv = new AdxDataValue();
String dataElement = getCodeFromClazz(DHISDataElement.class,
DATA_ELEMETS_PATH + dv.getDataElement() + JSON_POST_FIX);
if (StringUtils.isNotBlank(dataElement)) {
adxDv.setDataElement(dataElement);
adxDv.setValue(new BigDecimal(Integer.parseInt(dv.getValue())));
if (StringUtils.isNotBlank(dv.getCategoryOptionCombo())) {
DHISCategoryCombo c = getCategoryComboFromOption(dv.getCategoryOptionCombo());
DHISCategoryOptionCombo oc = getCategoryOptionCombo(dv.getCategoryOptionCombo());
if (c != null && oc != null)
adxDv.getOtherAttributes().put(
new QName(StringUtils.isNotBlank(c.getCode()) ? c.getCode() : c.getId()),
StringUtils.isNotBlank(oc.getCode()) ? oc.getCode() : oc.getId());
}
group.getDataValues().add(adxDv);
}
}
adx.getGroups().add(group);
}
catch (DatatypeConfigurationException e) {
e.printStackTrace();
}
}
return adx;
}
/**
* TODO this should support selection of a failed attempt(s) to push again
*/
@Override
public void postPreviouslyFailedData() {
subDirectoryJSONAndXMLFilePost(new File(OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DATA_FOLDER));
}
private void subDirectoryJSONAndXMLFilePost(File file) {
if (file != null && file.exists()) {
if (file.isFile() && (file.getName().endsWith(".json") || file.getName().endsWith(".xml"))) {
try {
String data = FileUtils.readFileToString(file);
String endPoint = file.getPath()
.replace(OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DATA_FOLDER, "")
.replace(File.separator + file.getName(), "");
if (StringUtils.isNotBlank(data) && StringUtils.isNotBlank(endPoint)) {
file.delete();
postDataToDHISEndpoint(endPoint, data);
}
}
catch (IOException e) {
e.printStackTrace();
}
} else if (file.isDirectory()) {
for (File f : file.listFiles()) {
subDirectoryJSONAndXMLFilePost(f);
}
}
}
}
@Override
public Integer getNumberOfFailedDataPosts() {
File dataDir = new File(OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DATA_FOLDER);
if (dataDir.exists() && dataDir.isDirectory()) {
for (File f : dataDir.listFiles()) {
subDirectoryJSONAndXMLFileCount(f);
}
}
return count;
}
private void subDirectoryJSONAndXMLFileCount(File dataDir) {
if (dataDir != null && dataDir.exists()) {
if (dataDir.isFile() && (dataDir.getName().endsWith(".json") || dataDir.getName().endsWith(".xml")))
count++;
else if (dataDir.isDirectory()) {
for (File f : dataDir.listFiles()) {
subDirectoryJSONAndXMLFileCount(f);
}
}
}
}
private void backUpData(String endPoint, String data, String extension) {
if (StringUtils.isNotBlank(endPoint) && StringUtils.isNotBlank(data)) {
if (StringUtils.isBlank(extension))
extension = ".json";
if (!endPoint.startsWith(File.separator))
endPoint = File.separator + endPoint;
String dataLocation = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DATA_FOLDER + endPoint;
File dataFile = new File(dataLocation);
if (!dataFile.exists())
dataFile.mkdirs();
String datafileLocation = dataFile.getPath() + File.separator
+ new SimpleDateFormat("ddMMyyy_hhmm").format(new Date()) + extension;
File datafile = new File(datafileLocation);
if (!datafile.exists()) {
try {
FileUtils.writeStringToFile(datafile, data);
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public String postDataToDHISEndpoint(String endpoint, String data) {
String url = Context.getAdministrationService().getGlobalProperty("dhisconnector.url");
String user = Context.getAdministrationService().getGlobalProperty("dhisconnector.user");
String pass = Context.getAdministrationService().getGlobalProperty("dhisconnector.pass");
DefaultHttpClient client = null;
String payload = "";
String extension = ".json";
try {
URL dhisURL = new URL(url);
String host = dhisURL.getHost();
int port = dhisURL.getPort();
HttpHost targetHost = new HttpHost(host, port, dhisURL.getProtocol());
client = new DefaultHttpClient();
BasicHttpContext localcontext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(
dhisURL.getPath() + endpoint + (configs.useAdxInsteadOfDxf() ? (endpoint.indexOf("?") > -1 ? "&"
: "?" + "dataElementIdScheme=CODE&orgUnitIdScheme=CODE&idScheme=CODE") : ""));
Credentials creds = new UsernamePasswordCredentials(user, pass);
Header bs = new BasicScheme().authenticate(creds, httpPost, localcontext);
httpPost.addHeader("Authorization", bs.getValue());
if (configs.useAdxInsteadOfDxf()) {
extension = ".xml";
httpPost.addHeader("Content-Type", "application/xml+adx");
httpPost.addHeader("Accept", "application/xml");
} else {
httpPost.addHeader("Content-Type", "application/json");
httpPost.addHeader("Accept", "application/json");
}
httpPost.setEntity(new StringEntity(data));
HttpResponse response = client.execute(targetHost, httpPost, localcontext);
HttpEntity entity = response.getEntity();
if (entity != null) {
payload = EntityUtils.toString(entity);
} else {
backUpData(endpoint, data, extension);
System.out.println("Failed to get entity from dhis2 server, network failure!");
}
}
catch (Exception ex) {
backUpData(endpoint, data, extension);
ex.printStackTrace();
}
finally {
if (client != null) {
client.getConnectionManager().shutdown();
}
}
return payload;
}
@Override
public boolean testDHISServerDetails(String url, String user, String pass) {
URL testURL;
Boolean success = true;
// Check if the URL makes sense
try {
testURL = new URL(url + "/api/resources"); // Add the root API
// endpoint to the URL
}
catch (MalformedURLException e) {
e.printStackTrace();
return false;
}
HttpHost targetHost = new HttpHost(testURL.getHost(), testURL.getPort(), testURL.getProtocol());
DefaultHttpClient httpclient = new DefaultHttpClient();
BasicHttpContext localcontext = new BasicHttpContext();
try {
HttpGet httpGet = new HttpGet(testURL.toURI());
Credentials creds = new UsernamePasswordCredentials(user, pass);
Header bs = new BasicScheme().authenticate(creds, httpGet, localcontext);
httpGet.addHeader("Authorization", bs.getValue());
httpGet.addHeader("Content-Type", "application/json");
httpGet.addHeader("Accept", "application/json");
HttpResponse response = httpclient.execute(targetHost, httpGet, localcontext); // Execute
// the
// test
// query
if (response.getStatusLine().getStatusCode() != 200) {
success = false;
}
}
catch (Exception ex) {
ex.printStackTrace();
success = false;
}
finally {
httpclient.getConnectionManager().shutdown();
}
return success;
}
@Override
public Object saveMapping(DHISMapping mapping) {
String mappingsDirecoryPath = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_MAPPINGS_FOLDER;
File mappingsDirecory = new File(mappingsDirecoryPath);
if (!mappingsDirecory.exists()) {
try {
if (!mappingsDirecory.mkdirs()) {
return null;
}
}
catch (Exception e) {
e.printStackTrace();
return e;
}
}
String filename = mapping.getName() + "." + mapping.getCreated() + ".mapping.json";
File newMappingFile = new File(mappingsDirecoryPath + File.separator + filename);
if (newMappingFile.exists()) {//user is trying to edit a mapping, delete previous copy first
newMappingFile.delete();
}
ObjectMapper mapper = new ObjectMapper();
try {
mapper.writeValue(newMappingFile, mapping);
}
catch (Exception e) {
e.printStackTrace();
return e;
}
return mapping;
}
@Override
public String getAdxFromDxf(DHISDataValueSet dataValueSet) {
return beautifyXML(
factory.translateAdxDataValueSetIntoString(convertDHISDataValueSetToAdxDataValueSet(dataValueSet)));
}
@Override
public Object postDataValueSet(DHISDataValueSet dataValueSet) {
ObjectMapper mapper = new ObjectMapper();
String jsonOrXmlString;
String responseString;
try {
jsonOrXmlString = configs.useAdxInsteadOfDxf()
? factory.translateAdxDataValueSetIntoString(convertDHISDataValueSetToAdxDataValueSet(dataValueSet))
: mapper.writeValueAsString(dataValueSet);
responseString = postDataToDHISEndpoint(DATAVALUESETS_PATH, jsonOrXmlString);
if (StringUtils.isNotBlank(responseString)) {
if (configs.useAdxInsteadOfDxf()) {
JAXBContext jaxbImportSummaryContext = JAXBContext.newInstance(ImportSummaries.class);
Unmarshaller importSummaryUnMarshaller = jaxbImportSummaryContext.createUnmarshaller();
return (ImportSummaries) importSummaryUnMarshaller.unmarshal(new StringReader(responseString));
} else {
return mapper.readValue(responseString, DHISImportSummary.class);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public List<DHISMapping> getMappings() {
List<DHISMapping> mappings = new ArrayList<DHISMapping>();
ObjectMapper mapper = new ObjectMapper();
String mappingsDirecoryPath = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_MAPPINGS_FOLDER;
File mappingsDirecory = new File(mappingsDirecoryPath);
File[] files = mappingsDirecory.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(DHISCONNECTOR_MAPPING_FILE_SUFFIX);
}
});
if (files == null)
return null;
for (File f : files) {
try {
mappings.add(mapper.readValue(f, DHISMapping.class));
}
catch (Exception e) {
e.printStackTrace();
}
}
return mappings;
}
@Override
public List<PeriodIndicatorReportDefinition> getReportWithMappings(List<DHISMapping> mappings) {
List<ReportDefinition> all = Context.getService(ReportDefinitionService.class).getAllDefinitions(false);
List<PeriodIndicatorReportDefinition> pireports = new ArrayList<PeriodIndicatorReportDefinition>();
for (ReportDefinition r : all) {
if (r instanceof PeriodIndicatorReportDefinition && mappingsHasGUID(mappings, r.getUuid())) {
pireports.add((PeriodIndicatorReportDefinition) r);
}
}
return pireports;
}
@Override
public List<DHISOrganisationUnit> getDHISOrgUnits() {
List<DHISOrganisationUnit> orgUnits = new ArrayList<DHISOrganisationUnit>();
ObjectMapper mapper = new ObjectMapper();
String jsonResponse = new String();
JsonNode node;
jsonResponse = getDataFromDHISEndpoint(DHISCONNECTOR_ORGUNIT_RESOURCE);
try {
node = mapper.readTree(jsonResponse);
orgUnits = Arrays
.asList(mapper.readValue(node.get("organisationUnits").toString(), DHISOrganisationUnit[].class));
}
catch (Exception ex) {
System.out.print(ex.getMessage());
}
return orgUnits;
}
private boolean mappingsHasGUID(List<DHISMapping> mappings, String GUID) {
if (mappings == null)
return false;
for (DHISMapping mapping : mappings) {
if (mapping.getPeriodIndicatorReportGUID().equals(GUID)) {
return true;
}
}
return false;
}
@SuppressWarnings("rawtypes")
@Override
public String uploadMappings(MultipartFile mapping) {
String msg = "";
String tempFolderName = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_TEMP_FOLDER + File.separator;
String mappingFolderName = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_MAPPINGS_FOLDER
+ File.separator;
String mappingName = mapping.getOriginalFilename();
if (mappingName.endsWith(".zip")) {
boolean allFailed = true;
File tempMappings = new File(tempFolderName + mappingName);
(new File(tempFolderName)).mkdirs();
try {
mapping.transferTo(tempMappings);
try {
ZipFile zipfile = new ZipFile(tempMappings);
for (Enumeration e = zipfile.entries(); e.hasMoreElements();) {
ZipEntry entry = (ZipEntry) e.nextElement();
if (entry.isDirectory()) {
System.out.println(
"Incorrect file (Can't be a folder instead): " + entry.getName() + " has been ignored");
} else if (entry.getName().endsWith(DHISCONNECTOR_MAPPING_FILE_SUFFIX)) {
File outputFile = new File(mappingFolderName, entry.getName());
if (outputFile.exists()) {
System.out.println("File: " + outputFile.getName() + " already exists and has been ignored");
} else {
BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry));
BufferedOutputStream outputStream = new BufferedOutputStream(
new FileOutputStream(outputFile));
try {
System.out.println("Extracting: " + entry);
IOUtils.copy(inputStream, outputStream);
allFailed = false;
}
finally {
outputStream.close();
inputStream.close();
}
}
} else {
System.out.println("Incorrect file: " + entry.getName() + " has been ignored");
}
}
if (!allFailed) {
msg = Context.getMessageSourceService().getMessage("dhisconnector.uploadMapping.groupSuccess");
} else {
msg = Context.getMessageSourceService().getMessage("dhisconnector.uploadMapping.allFailed");
}
FileUtils.deleteDirectory(new File(tempFolderName));
}
catch (Exception e) {
System.out.println("Error while extracting file:" + mapping.getName() + " ; " + e);
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
} else if (mappingName.endsWith(DHISCONNECTOR_MAPPING_FILE_SUFFIX)) {
try {
File uploadedMapping = new File(mappingFolderName + mappingName);
if (uploadedMapping.exists()) {
msg = Context.getMessageSourceService().getMessage("dhisconnector.uploadMapping.exists");
} else {
mapping.transferTo(uploadedMapping);
msg = Context.getMessageSourceService().getMessage("dhisconnector.uploadMapping.singleSuccess");
}
}
catch (IllegalStateException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
} else {
msg = Context.getMessageSourceService().getMessage("dhisconnector.uploadMapping.wrongType");
}
return msg;
}
@Override
public String[] exportSelectedMappings(String[] selectedMappings) {
String[] cleanedSelectedMappings = cleanSelectedMappings(selectedMappings);
String msg = "";
String[] returnStr = new String[2];
String path = null;
try {
byte[] buffer = new byte[1024];
String sourceDirectory = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_MAPPINGS_FOLDER
+ File.separator;
String tempFolderName = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_TEMP_FOLDER + File.separator;
String suffix = ".mapping.json";
String zipFile = tempFolderName + "exported-mappings_" + (new Date()).getTime() + ".zip";
(new File(tempFolderName)).mkdirs();
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
File dir = new File(sourceDirectory);
if (!dir.isDirectory()) {
System.out.println(sourceDirectory + " is not a directory");
} else {
File[] files = dir.listFiles();
String mappings = "";
if (files.length == 0) {
msg = Context.getMessageSourceService().getMessage("dhisconnector.exportMapping.noMappingsFound");
} else {
for (int i = 0; i < files.length; i++) {
if (files[i].getName().endsWith(suffix)) {
FileInputStream fin = new FileInputStream(files[i]);
mappings += files[i].getName() + "<:::>";
System.out.println("Compressing " + files[i].getName());
if (cleanedSelectedMappings.length == 0) {
copyToZip(buffer, zout, files, i, fin);
} else {
if (selectedMappingsIncludes(cleanedSelectedMappings, files[i].getName())) {
copyToZip(buffer, zout, files, i, fin);
}
}
msg = Context.getMessageSourceService().getMessage("dhisconnector.exportMapping.success");
zout.closeEntry();
fin.close();
}
}
if (mappings.split("<:::>").length == 0) {
msg = Context.getMessageSourceService().getMessage("dhisconnector.exportMapping.noMappingsFound");
}
path = zipFile;
}
}
zout.close();
System.out.println("Zip file has been created!");
}
catch (IOException e) {
e.printStackTrace();
}
returnStr[0] = msg;
returnStr[1] = path;
return returnStr;
}
private String[] cleanSelectedMappings(String[] selectedMappings) {
int r, w;
final int n = r = w = selectedMappings.length;
while (r > 0) {
final String s = selectedMappings[--r];
if (!s.equals("null")) {
selectedMappings[--w] = s;
}
}
return Arrays.copyOfRange(selectedMappings, w, n);
}
private void copyToZip(byte[] buffer, ZipOutputStream zout, File[] files, int i, FileInputStream fin)
throws IOException {
zout.putNextEntry(new ZipEntry(files[i].getName()));
int length;
while ((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
}
private boolean selectedMappingsIncludes(String[] selectedMappings, String name) {
boolean contains = false;
for (int i = 0; i < selectedMappings.length; i++) {
if ((selectedMappings[i] + DHISCONNECTOR_MAPPING_FILE_SUFFIX).equals(name)) {
contains = true;
}
}
return contains;
}
@Override
public boolean dhis2BackupExists() {
File backup = new File(
OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER + File.separator + "api");
if (backup.exists() && backup.isDirectory() && backup.list().length > 0) {
return true;
} else {
return false;
}
}
@SuppressWarnings("deprecation")
@Override
public String getLastSyncedAt() {
File backup = new File(
OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER + File.separator + "api");
if (dhis2BackupExists()) {
Date lastModified = new Date(backup.lastModified());
return Context.getDateFormat().format(lastModified) + " " + lastModified.getHours() + ":"
+ lastModified.getMinutes() + ":" + lastModified.getSeconds();
} else {
return "";
}
}
@Override
public String getDHIS2APIBackupPath() {
String zipFile = null;
String sourceDirectory = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER
+ File.separator;
String tempFolderName = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_TEMP_FOLDER + File.separator;
File temp = new File(tempFolderName);
if (!temp.exists()) {
temp.mkdirs();
}
zipFile = tempFolderName + "exported-dhis2APIBackup_" + (new Date()).getTime() + ".zip";
File dirObj = new File(sourceDirectory);
ZipOutputStream out;
try {
out = new ZipOutputStream(new FileOutputStream(zipFile));
System.out.println("Creating : " + zipFile);
addDHIS2APIDirectories(dirObj, out, sourceDirectory);
out.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return zipFile;
}
private void addDHIS2APIDirectories(File dirObj, ZipOutputStream out, String sourceDirectory) {
File[] files = dirObj.listFiles();
byte[] tmpBuf = new byte[1024];
for (int i = 0; i < files.length; i++) {
if (matchingDHIS2APIBackUpStructure(files[i])) {
if (files[i].isDirectory()) {
addDHIS2APIDirectories(files[i], out, sourceDirectory);
continue;
}
try {
FileInputStream in = new FileInputStream(files[i].getAbsolutePath());
String entryPath = (new File(sourceDirectory)).toURI().relativize(files[i].toURI()).getPath();
System.out.println("Adding: " + entryPath);
out.putNextEntry(new ZipEntry(entryPath));
int len;
while ((len = in.read(tmpBuf)) > 0) {
out.write(tmpBuf, 0, len);
}
out.closeEntry();
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
private boolean matchingDHIS2APIBackUpStructure(File file) {
return StringUtils.equals(file.getName(), "api") || StringUtils.equals(file.getName(), "categoryCombos")
|| StringUtils.equals(file.getName(), "dataElements") || StringUtils.equals(file.getName(), "dataSets")
|| StringUtils.equals(file.getName(), "organisationUnits.json?paging=false&fields=id,name")
|| StringUtils.equals(file.getName(), "dataSets.json?paging=false&fields=id,name")
|| file.getName().endsWith(".json");
}
@Override
public String uploadDHIS2APIBackup(MultipartFile dhis2APIBackup) {
String msg = "";
String outputFolder = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_TEMP_FOLDER;
File temp = new File(outputFolder);
File dhis2APIBackupRootDir = new File(OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_DHIS2BACKUP_FOLDER);
if (!temp.exists()) {
temp.mkdirs();
}
File dest = new File(outputFolder + File.separator + dhis2APIBackup.getOriginalFilename());
if (!dhis2APIBackup.isEmpty() && dhis2APIBackup.getOriginalFilename().endsWith(".zip")) {
try {
dhis2APIBackup.transferTo(dest);
if (dest.exists() && dest.isFile()) {
File unzippedAt = new File(outputFolder + File.separator + "api");
File api = new File(dhis2APIBackupRootDir.getPath() + File.separator + "api");
unZipDHIS2APIBackupToTemp(dest.getCanonicalPath());
if ((new File(outputFolder)).list().length > 0 && unzippedAt.exists()) {
if (!dhis2APIBackupRootDir.exists()) {
dhis2APIBackupRootDir.mkdirs();
}
if (FileUtils.sizeOfDirectory(dhis2APIBackupRootDir) > 0 && unzippedAt.exists()
&& unzippedAt.isDirectory()) {
if (checkIfDirContainsFile(dhis2APIBackupRootDir, "api")) {
FileUtils.deleteDirectory(api);
api.mkdir();
msg = Context.getMessageSourceService()
.getMessage("dhisconnector.dhis2backup.replaceSuccess");
} else {
msg = Context.getMessageSourceService()
.getMessage("dhisconnector.dhis2backup.import.success");
}
FileUtils.copyDirectory(unzippedAt, api);
FileUtils.deleteDirectory(temp);
}
}
}
}
catch (IllegalStateException e) {
msg = Context.getMessageSourceService().getMessage("dhisconnector.dhis2backup.failure");
e.printStackTrace();
}
catch (IOException e) {
msg = Context.getMessageSourceService().getMessage("dhisconnector.dhis2backup.failure");
e.printStackTrace();
}
} else {
msg = Context.getMessageSourceService().getMessage("dhisconnector.dhis2backup.failure");
}
return msg;
}
private boolean checkIfDirContainsFile(File dir, String fileName) {
boolean contains = false;
if (dir.exists() && dir.isDirectory()) {
for (File d : dir.listFiles()) {
if (d.getName().equals(fileName))//can be directory still
contains = true;
}
}
return contains;
}
private void unZipDHIS2APIBackupToTemp(String zipFile) {
byte[] buffer = new byte[1024];
String outputFolder = OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_TEMP_FOLDER;
try {
File destDir = new File(outputFolder);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String filePath = outputFolder + File.separator + entry.getName();
if (!entry.isDirectory()) {
if (!(new File(filePath)).getParentFile().exists()) {
(new File(filePath)).getParentFile().mkdirs();
}
(new File(filePath)).createNewFile();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = buffer;
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
} else {
// if the entry is a directory, make the directory
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
@Override
public DHISMapping getMapping(String s) {
File mappingsFolder = new File(OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_MAPPINGS_FOLDER);
final String mapping = s.replace("[@]",
".");/*meant to be uuid, however we are hacking it to contain what we want (mappingName<@>dateTimeStampWhenCreated)*/
DHISMapping mappingObj = null;
if (mappingsFolder.exists() && checkIfDirContainsFile(mappingsFolder, mapping + DHISCONNECTOR_MAPPING_FILE_SUFFIX)) {
ObjectMapper mapper = new ObjectMapper();
File[] files = mappingsFolder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.equals(mapping + DHISCONNECTOR_MAPPING_FILE_SUFFIX);
}
});
if (files.length == 1 && files[0] != null) {
try {
mappingObj = mapper.readValue(files[0], DHISMapping.class);
}
catch (JsonParseException e) {
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
return mappingObj;
}
@Override
public boolean permanentlyDeleteMapping(DHISMapping mapping) {
File mappingsFolder = new File(OpenmrsUtil.getApplicationDataDirectory() + DHISCONNECTOR_MAPPINGS_FOLDER);
boolean deleted = false;
if (mapping != null) {
String mappingFileName = mapping.getName() + "." + mapping.getCreated() + DHISCONNECTOR_MAPPING_FILE_SUFFIX;
if (checkIfDirContainsFile(mappingsFolder, mappingFileName)) {
try {
if ((new File(mappingsFolder.getCanonicalPath() + File.separator + mappingFileName)).delete()) {
deleted = true;
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
return deleted;
}
private String beautifyXML(String xml) {
if (StringUtils.isNotBlank(xml)) {
try {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new InputSource(new ByteArrayInputStream(xml.getBytes("utf-8"))));
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.INDENT, "yes");
Writer out = new StringWriter();
tf.transform(new DOMSource(document), new StreamResult(out));
return out.toString();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (SAXException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
catch (ParserConfigurationException e) {
e.printStackTrace();
}
catch (TransformerException e) {
e.printStackTrace();
}
}
return xml;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment