EsvGovernmentBodyOperationOutcomeReaderImpl.java
/*
* Copyright 2010-2019 James Pether Sörling
*
* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id$
* $HeadURL$
*/
package com.hack23.cia.service.external.esv.impl;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.Month;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.codec.Charsets;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.http.client.fluent.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.hack23.cia.service.external.esv.api.GovernmentBodyAnnualOutcomeSummary;
import com.hack23.cia.service.external.esv.api.GovernmentBodyAnnualSummary;
/**
* The Class EsvGovernmentBodyOperationOutcomeReaderImpl.
*/
@Component
final class EsvGovernmentBodyOperationOutcomeReaderImpl implements EsvGovernmentBodyOperationOutcomeReader {
/** The Constant ORGANISATIONSNUMMER. */
private static final String ORGANISATIONSNUMMER = "Organisationsnummer";
/** The Constant MYNDIGHET. */
private static final String MYNDIGHET = "Myndighet";
/** The Constant ÅR. */
private static final String YEAR = "År";
/** The Constant UTFALL_DECEMBER. */
private static final String UTFALL_DECEMBER = "Utfall december";
/** The Constant UTFALL_NOVEMBER. */
private static final String UTFALL_NOVEMBER = "Utfall november";
/** The Constant UTFALL_OKTOBER. */
private static final String UTFALL_OKTOBER = "Utfall oktober";
/** The Constant UTFALL_SEPTEMBER. */
private static final String UTFALL_SEPTEMBER = "Utfall september";
/** The Constant UTFALL_AUGUSTI. */
private static final String UTFALL_AUGUSTI = "Utfall augusti";
/** The Constant UTFALL_JULI. */
private static final String UTFALL_JULI = "Utfall juli";
/** The Constant UTFALL_JUNI. */
private static final String UTFALL_JUNI = "Utfall juni";
/** The Constant UTFALL_MAJ. */
private static final String UTFALL_MAJ = "Utfall maj";
/** The Constant UTFALL_APRIL. */
private static final String UTFALL_APRIL = "Utfall april";
/** The Constant UTFALL_MARS. */
private static final String UTFALL_MARS = "Utfall mars";
/** The Constant UTFALL_FEBRUARI. */
private static final String UTFALL_FEBRUARI = "Utfall februari";
/** The Constant UTFALL_JANUARI. */
private static final String UTFALL_JANUARI = "Utfall januari";
/** The Constant SPECIFIC_OUTGOING_FIELDS. */
private static final String[] SPECIFIC_OUTGOING_FIELDS = new String[] { "Inkomsttyp", "Inkomsttypsnamn", "Inkomsthuvudgrupp", "Inkomsthuvudgruppsnamn", "Inkomsttitelgrupp", "Inkomsttitelgruppsnamn", "Inkomsttitel", "Inkomsttitelsnamn", "Inkomstundertitel", "Inkomstundertitelsnamn"};
/** The Constant SPECIFIC_INCOMING_FIELDS. */
private static final String[] SPECIFIC_INCOMING_FIELDS = new String[] { "Utgiftsområde", "Utgiftsområdesnamn", "Anslag", "Anslagsnamn", "Anslagspost", "Anslagspostsnamn", "Anslagsdelpost", "Anslagsdelpostsnamn"};
/** The esv excel reader. */
@Autowired
private EsvExcelReader esvExcelReader;
private List<GovernmentBodyAnnualOutcomeSummary> incomeCsvValues;
private List<GovernmentBodyAnnualOutcomeSummary> outGoingCsvValues;
/**
* Instantiates a new esv government body operation outcome reader impl.
*/
public EsvGovernmentBodyOperationOutcomeReaderImpl() {
super();
}
@Override
public synchronized List<GovernmentBodyAnnualOutcomeSummary> readIncomeCsv() throws IOException {
if (incomeCsvValues == null) {
incomeCsvValues = readUsingZipInputStream(Request.Get(
"https://www.esv.se/psidata/manadsutfall/GetFile/?documentType=Inkomst&fileType=Zip&fileName=M%C3%A5nadsutfall%20inkomster%20januari%202006%20-%20juli%202019,%20definitivt.zip&year=2019&month=7&status=Definitiv")
.execute().returnContent().asStream(),SPECIFIC_OUTGOING_FIELDS);
}
return Collections.unmodifiableList(incomeCsvValues);
}
@Override
public synchronized List<GovernmentBodyAnnualOutcomeSummary> readOutgoingCsv() throws IOException {
if (outGoingCsvValues == null) {
outGoingCsvValues = readUsingZipInputStream(Request.Get(
"https://www.esv.se/psidata/manadsutfall/GetFile/?documentType=Utgift&fileType=Zip&fileName=M%C3%A5nadsutfall%20utgifter%20januari%202006%20-%20juli%202019,%20definitivt.zip&year=2019&month=7&status=Definitiv")
.execute().returnContent().asStream(),SPECIFIC_INCOMING_FIELDS);
}
return Collections.unmodifiableList(outGoingCsvValues);
}
/**
* Read using zip input stream.
*
* @param inputStream
* the input stream
* @param specificFields
* the specific fields
* @return the list
* @throws IOException
* Signals that an I/O exception has occurred.
*/
private List<GovernmentBodyAnnualOutcomeSummary> readUsingZipInputStream(final InputStream inputStream,final String[] specificFields) throws IOException {
final BufferedInputStream bis = new BufferedInputStream(inputStream);
final ZipInputStream is = new ZipInputStream(bis);
final List<GovernmentBodyAnnualOutcomeSummary> list = new ArrayList<>();
try {
ZipEntry entry;
while ((entry = is.getNextEntry()) != null) {
list.addAll(readCsvContent(is,specificFields));
}
} finally {
is.close();
}
return list;
}
/**
* Read csv content.
*
* @param is
* the is
* @param specificFields
* the specific fields
* @return the list
* @throws IOException
* Signals that an I/O exception has occurred.
*/
private List<GovernmentBodyAnnualOutcomeSummary> readCsvContent(final InputStream is,final String[] specificFields) throws IOException {
final CSVParser parser = CSVParser.parse(new InputStreamReader(is,Charsets.UTF_8), CSVFormat.EXCEL.withHeader().withDelimiter(';'));
final List<CSVRecord> records = parser.getRecords();
records.remove(0);
final Map<Integer, Map<String,String>> orgMinistryMap = createOrgMinistryMap(esvExcelReader.getDataPerMinistry(null));
final List<GovernmentBodyAnnualOutcomeSummary> list = new ArrayList<>();
for (final CSVRecord csvRecord : records) {
final GovernmentBodyAnnualOutcomeSummary governmentBodyAnnualOutcomeSummary = new GovernmentBodyAnnualOutcomeSummary(csvRecord.get(MYNDIGHET), csvRecord.get(ORGANISATIONSNUMMER), orgMinistryMap.get(Integer.valueOf(csvRecord.get(YEAR))).get(csvRecord.get(ORGANISATIONSNUMMER).replaceAll("-", "")), Integer.parseInt(csvRecord.get(YEAR)));
for (final String field : specificFields) {
governmentBodyAnnualOutcomeSummary.addDescriptionField(field,csvRecord.get(field));
}
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.JANUARY.getValue(),csvRecord.get(UTFALL_JANUARI));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.FEBRUARY.getValue(),csvRecord.get(UTFALL_FEBRUARI));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.MARCH.getValue(),csvRecord.get(UTFALL_MARS));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.APRIL.getValue(),csvRecord.get(UTFALL_APRIL));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.MAY.getValue(),csvRecord.get(UTFALL_MAJ));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.JUNE.getValue(),csvRecord.get(UTFALL_JUNI));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.JULY.getValue(),csvRecord.get(UTFALL_JULI));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.AUGUST.getValue(),csvRecord.get(UTFALL_AUGUSTI));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.SEPTEMBER.getValue(),csvRecord.get(UTFALL_SEPTEMBER));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.OCTOBER.getValue(),csvRecord.get(UTFALL_OKTOBER));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.NOVEMBER.getValue(),csvRecord.get(UTFALL_NOVEMBER));
addResultForMonth(governmentBodyAnnualOutcomeSummary,Month.DECEMBER.getValue(),csvRecord.get(UTFALL_DECEMBER));
list.add(governmentBodyAnnualOutcomeSummary);
}
return list;
}
/**
* Creates the org ministry map.
*
* @param data the data
* @return the map
*/
private static Map<Integer, Map<String, String>> createOrgMinistryMap(
final Map<Integer, List<GovernmentBodyAnnualSummary>> data) {
final Map<Integer, Map<String,String>> orgMinistryMap = new HashMap<>();
final Set<Entry<Integer, List<GovernmentBodyAnnualSummary>>> entrySet = data.entrySet();
for (final Entry<Integer, List<GovernmentBodyAnnualSummary>> entry : entrySet) {
orgMinistryMap.put(entry.getKey(), entry.getValue().stream().collect(Collectors.groupingBy(t -> t.getOrgNumber().replaceAll("-","") ,Collectors.collectingAndThen(
Collectors.toList(),
values -> values.get(0).getMinistry()))));
}
return orgMinistryMap;
}
/**
* Adds the result for month.
*
* @param governmentBodyAnnualOutcomeSummary
* the government body annual outcome summary
* @param month
* the month
* @param value
* the value
*/
private static void addResultForMonth(final GovernmentBodyAnnualOutcomeSummary governmentBodyAnnualOutcomeSummary, final int month,
final String value) {
if (value != null && value.length() >0 ) {
governmentBodyAnnualOutcomeSummary.addData(month,Double.valueOf(value.replaceAll(",", ".")));
}
}
}