diff --git a/pom.xml b/pom.xml
index e47fc32..78e5d11 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,9 +4,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- mmauro
+ org.github.mmauro94
siopeDownloader
- 1.0-SNAPSHOT
+ 1.0.0
org.apache.commons
diff --git a/src/main/java/SiopeEntrateDownloader.java b/src/main/java/SiopeEntrateDownloader.java
deleted file mode 100644
index dbee412..0000000
--- a/src/main/java/SiopeEntrateDownloader.java
+++ /dev/null
@@ -1,59 +0,0 @@
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-public class SiopeEntrateDownloader {
-
- private final static String BASE_URL = "https://www.siope.it/Siope2Web/documenti/siope2/open/last/";
-
- private final int year;
-
- public SiopeEntrateDownloader(int year) {
- if (year < 1990) {
- throw new IllegalArgumentException("Year must be >= 1990");
- }
- this.year = year;
- }
-
- @NotNull
- private URL getEntrateUrl() throws MalformedURLException {
- return new URL(BASE_URL + "SIOPE_USCITE." + year + ".zip");
- }
-
- @NotNull
- private URL getUsciteUrl() throws MalformedURLException {
- return new URL(BASE_URL + "SIOPE_USCITE." + year + ".zip");
- }
-
- @NotNull
- public SiopeInputStream downloadEntrate() throws IOException {
- return download(getEntrateUrl());
- }
-
-
- @NotNull
- public SiopeInputStream downloadUscite() throws IOException {
- return download(getUsciteUrl());
- }
-
- @NotNull
- private SiopeInputStream download(@NotNull URL url) throws IOException {
- final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- if (urlConnection.getResponseCode() == 200) {
- final ZipInputStream zis = new ZipInputStream(urlConnection.getInputStream());
- final ZipEntry entry = zis.getNextEntry();
- if (!entry.getName().endsWith(".csv")) {
- throw new IllegalStateException("File contained in zip file is not a csv");
- } else {
- return new SiopeInputStream(zis);
- }
- } else {
- throw new IOException("Response code: " + urlConnection.getResponseCode() + ", " + urlConnection.getResponseMessage());
- }
- }
-}
diff --git a/src/main/java/SiopeInputStream.java b/src/main/java/SiopeInputStream.java
deleted file mode 100644
index d9a0f0a..0000000
--- a/src/main/java/SiopeInputStream.java
+++ /dev/null
@@ -1,24 +0,0 @@
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.ZipInputStream;
-
-public class SiopeInputStream extends InputStream {
-
- @NotNull
- private final ZipInputStream zis;
-
- public SiopeInputStream(@NotNull ZipInputStream zis) {
- this.zis = zis;
- }
-
- public int read() throws IOException {
- return zis.read();
- }
-
- @Override
- public void close() throws IOException {
- zis.close();
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/AutoMap.java b/src/main/java/mmauro/siopeDownloader/datastruct/AutoMap.java
deleted file mode 100644
index 2922364..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/AutoMap.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package mmauro.siopeDownloader.datastruct;
-
-import mmauro.siopeDownloader.utils.CSVRecordParser;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-public abstract class AutoMap implements Collection {
-
- public interface AutoMapCreator> {
- T create();
- }
-
- @NotNull
- private final HashMap map = new HashMap<>();
-
- public AutoMap() {
- }
-
- @NotNull
- protected abstract K getKey(@NotNull V value);
-
- @NotNull
- public V get(@NotNull K key) {
- if (!map.containsKey(key)) {
- throw new IllegalStateException("Value with key " + key + " not found");
- }
- return map.get(key);
- }
-
- public void put(@NotNull V value) {
- map.put(getKey(value), value);
- }
-
- public boolean hasKey(@NotNull K key) {
- return map.containsKey(key);
- }
-
- public boolean hasValue(@NotNull V key) {
- return map.containsValue(key);
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public boolean contains(Object o) {
- return map.containsValue(o);
- }
-
- @NotNull
- @Override
- public Iterator iterator() {
- return map.values().iterator();
- }
-
- @NotNull
- @Override
- public Object[] toArray() {
- return map.values().toArray();
- }
-
- @NotNull
- @Override
- public T[] toArray(@NotNull T[] a) {
- return map.values().toArray(a);
- }
-
- @Override
- public boolean add(V v) {
- if (hasValue(v)) {
- put(v);
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public boolean remove(Object o) {
- return map.values().remove(o);
- }
-
- @Override
- public boolean containsAll(@NotNull Collection> c) {
- return map.values().containsAll(c);
- }
-
- @Override
- public boolean addAll(@NotNull Collection extends V> c) {
- boolean changed = false;
- for (V v : c) {
- changed |= add(v);
- }
- return changed;
- }
-
- @Override
- public boolean removeAll(@NotNull Collection> c) {
- return map.values().removeAll(c);
- }
-
- @Override
- public boolean retainAll(@NotNull Collection> c) {
- return map.values().retainAll(c);
- }
-
- @Override
- public void clear() {
- map.clear();
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- public static > T parse(@NotNull List records, @NotNull CSVRecordParser recordParser, @NotNull AutoMapCreator mapCreator) {
- T map = mapCreator.create();
- for (CSVRecord record : records) {
- map.put(recordParser.parse(record));
- }
- return map;
- }
-
- public static > T parse(@NotNull CSVParser parser, @NotNull CSVRecordParser recordParser, @NotNull AutoMapCreator mapCreator) throws IOException {
- return parse(parser.getRecords(), recordParser, mapCreator);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Anagrafiche.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Anagrafiche.java
deleted file mode 100644
index 145f05f..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Anagrafiche.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.Getter;
-import mmauro.siopeDownloader.download.SiopeZipDownloader;
-import mmauro.siopeDownloader.utils.ParseUtils;
-import mmauro.siopeDownloader.utils.ReaderUtils;
-import mmauro.siopeDownloader.utils.URLUtils;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-public class Anagrafiche {
-
- public static final String FILE_LOCATION = "/Siope2Web/documenti/siope2/open/last/SIOPE_ANAGRAFICHE.zip";
-
- @NotNull
- @Getter
- private final Comparto.Map comparti;
- @NotNull
- @Getter
- private final Sottocomparto.Map sottocomparti;
- @NotNull
- @Getter
- private final RipartizioneGeografica.Map ripartizioniGeografiche;
- @NotNull
- @Getter
- private final Regione.Map regioni;
- @NotNull
- @Getter
- private final Provincia.Map provincie;
- @NotNull
- @Getter
- private final Comune.Map comuni;
- @NotNull
- @Getter
- private final Ente.Map enti;
- @NotNull
- @Getter
- private final CodiceGestionaleEntrate.Map codiciGestionaliEntrate;
- @NotNull
- @Getter
- private final CodiceGestionaleUscite.Map codiciGestionaliUscite;
-
- private Anagrafiche(@NotNull Comparto.Map comparti, @NotNull Sottocomparto.Map sottocomparti, @NotNull RipartizioneGeografica.Map ripartizioniGeografiche, @NotNull Regione.Map regioni, @NotNull Provincia.Map provincie, @NotNull Comune.Map comuni, @NotNull Ente.Map enti, @NotNull CodiceGestionaleEntrate.Map codiciGestionaliEntrate, @NotNull CodiceGestionaleUscite.Map codiciGestionaliUscite) {
- this.comparti = comparti;
- this.sottocomparti = sottocomparti;
- this.ripartizioniGeografiche = ripartizioniGeografiche;
- this.regioni = regioni;
- this.provincie = provincie;
- this.comuni = comuni;
- this.enti = enti;
- this.codiciGestionaliEntrate = codiciGestionaliEntrate;
- this.codiciGestionaliUscite = codiciGestionaliUscite;
- }
-
- @NotNull
- public static Anagrafiche downloadAnagrafiche() throws IOException {
- ZipInputStream download = new SiopeZipDownloader(new URL(URLUtils.SIOPE_WEBSITE + FILE_LOCATION)).download();
- ZipEntry entry;
-
-
- List compartiRecords = null, sottocompartiRecords = null, regProvRecords = null, comuniRecords = null, entiRecords = null, codGestEntRecords = null, codGestUscRecords = null;
- while ((entry = download.getNextEntry()) != null) {
- final List records = CSVParser.parse(ReaderUtils.readAll(new InputStreamReader(download)), ParseUtils.CSV_FORMAT).getRecords();
-
- switch (entry.getName().substring(0, entry.getName().indexOf('.'))) {
- case "ANAG_COMPARTI":
- compartiRecords = records;
- break;
- case "ANAG_SOTTOCOMPARTI":
- sottocompartiRecords = records;
- break;
- case "ANAG_REG_PROV":
- regProvRecords = records;
- break;
- case "ANAG_COMUNI":
- case "ANAGRAFE_COMUNI":
- comuniRecords = records;
- break;
- case "ANAG_ENTI_SIOPE":
- entiRecords = records;
- break;
- case "ANAG_CODGEST_ENTRATE":
- codGestEntRecords = records;
- break;
- case "ANAG_CODGEST_USCITE":
- codGestUscRecords = records;
- continue;
- default:
- throw new IllegalStateException("Unexpected file: " + entry.getName());
- }
- }
- if (compartiRecords == null) {
- throw new IllegalStateException("File ANAG_COMPARTI not found");
- } else if (sottocompartiRecords == null) {
- throw new IllegalStateException("File ANAG_SOTTOCOMPARTI not found");
- } else if (regProvRecords == null) {
- throw new IllegalStateException("File ANAG_REG_PROV not found");
- } else if (comuniRecords == null) {
- throw new IllegalStateException("File ANAGRAFE_COMUNI/ANAG_COMUNI not found");
- }else if (entiRecords == null) {
- throw new IllegalStateException("File ANAG_ENTI_SIOPE not found");
- } else if(codGestEntRecords == null) {
- throw new IllegalStateException("File ANAG_CODGEST_ENTRATE not found");
- } else if(codGestUscRecords == null) {
- throw new IllegalStateException("File ANAG_CODGEST_USCITE not found");
- }
-
- final Comparto.Map comparti = Comparto.parseAll(compartiRecords);
- final Sottocomparto.Map sottocomparti = Sottocomparto.parseAll(sottocompartiRecords, comparti);
- final RipartizioneGeografica.Map ripartizioniGeografiche = RipartizioneGeografica.parseAll(regProvRecords);
- final Regione.Map regioni = Regione.parseAll(regProvRecords, ripartizioniGeografiche);
- final Provincia.Map provincie = Provincia.parseAll(regProvRecords, regioni);
- final Comune.Map comuni = Comune.parseAll(comuniRecords, provincie);
- final Ente.Map enti = Ente.parseAll(entiRecords, comuni, provincie, sottocomparti);
- final CodiceGestionaleEntrate.Map codiciGestionaliEntrate = CodiceGestionaleEntrate.parseAll(codGestEntRecords, comparti);
- final CodiceGestionaleUscite.Map codiciGestionaliUscite = CodiceGestionaleUscite.parseAll(codGestUscRecords, comparti);
-
- return new Anagrafiche(comparti, sottocomparti, ripartizioniGeografiche, regioni, provincie, comuni, enti, codiciGestionaliEntrate, codiciGestionaliUscite);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionale.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionale.java
deleted file mode 100644
index 562b262..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionale.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import mmauro.siopeDownloader.utils.CSVRecordParser;
-import mmauro.siopeDownloader.utils.ParseUtils;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.text.ParseException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-@EqualsAndHashCode(of = {"codice"})
-public abstract class CodiceGestionale {
-
- public static abstract class Map extends AutoMap {
-
- @NotNull
- @Override
- protected String getKey(@NotNull CodiceGestionale value) {
- return value.getCodice();
- }
- }
-
- public interface Creator> {
- T create(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita);
-
- M createMap();
- }
-
- @NotNull
- @Getter
- private final String codice;
- @NotNull
- @Getter
- private final String nome;
- @NotNull
- @Getter
- private final Comparto comparto;
- @NotNull
- @Getter
- private final Date inizioValidita;
- @Nullable
- @Getter
- private final Date fineValidita;
-
- protected CodiceGestionale(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
- this.codice = codice;
- this.nome = nome;
- this.comparto = comparto;
- this.inizioValidita = inizioValidita;
- this.fineValidita = fineValidita;
- }
-
- @NotNull
- public static T parse(@NotNull CSVRecord record, @NotNull Creator creator, @NotNull Comparto.Map comparti) {
- if (record.size() != 5) {
- throw new IllegalArgumentException("Record size != 5");
- } else {
- final String codice = record.get(0);
- final String codiceCategoriaComparto = record.get(1);
- final String nome = record.get(2);
- Date dataInizio, dataFine;
- synchronized (ParseUtils.DATE_FORMAT) {
- try {
- dataInizio = ParseUtils.DATE_FORMAT.parse(record.get(3));
- } catch (ParseException e) {
- throw new IllegalStateException("Illega l inizio validità date: " + record.get(1), e);
- }
- try {
- dataFine = ParseUtils.DATE_FORMAT.parse(record.get(4));
- Calendar cal = Calendar.getInstance();
- cal.setTime(dataFine);
- if (cal.get(Calendar.YEAR) == 9999 && cal.get(Calendar.MONTH) == Calendar.DECEMBER && cal.get(Calendar.DAY_OF_MONTH) == 31) {
- dataFine = null;
- }
- } catch (ParseException e) {
- throw new IllegalStateException("Illegal inserimento date: " + record.get(2), e);
- }
- }
- return creator.create(codice, nome, comparti.get(codiceCategoriaComparto), dataInizio, dataFine);
- }
- }
-
- @NotNull
- public static > M parseAll(@NotNull List records, @NotNull Creator creator, @NotNull Comparto.Map comparti) {
- return AutoMap.parse(records, x -> parse(x, creator, comparti), creator::createMap);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleEntrate.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleEntrate.java
deleted file mode 100644
index 8cb8fbc..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleEntrate.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Date;
-import java.util.List;
-
-public class CodiceGestionaleEntrate extends CodiceGestionale {
-
- public static class Map extends CodiceGestionale.Map {
-
- }
-
- protected CodiceGestionaleEntrate(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
- super(codice, nome, comparto, inizioValidita, fineValidita);
- }
-
- protected static final CodiceGestionale.Creator CREATOR = new CodiceGestionale.Creator() {
- @Override
- public CodiceGestionaleEntrate create(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
- return new CodiceGestionaleEntrate(codice, nome, comparto, inizioValidita, fineValidita);
- }
-
- @Override
- public Map createMap() {
- return new Map();
- }
- };
-
- @NotNull
- public static CodiceGestionaleEntrate.Map parseAll(@NotNull List records, @NotNull Comparto.Map comparti) {
- return CodiceGestionale.parseAll(records, CREATOR, comparti);
- }
-
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleUscite.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleUscite.java
deleted file mode 100644
index 333e2cf..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleUscite.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Date;
-import java.util.List;
-
-public class CodiceGestionaleUscite extends CodiceGestionale {
-
- public static class Map extends CodiceGestionale.Map {
-
- }
-
- protected CodiceGestionaleUscite(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
- super(codice, nome, comparto, inizioValidita, fineValidita);
- }
-
- protected static final Creator CREATOR = new Creator() {
- @Override
- public CodiceGestionaleUscite create(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
- return new CodiceGestionaleUscite(codice, nome, comparto, inizioValidita, fineValidita);
- }
-
- @Override
- public Map createMap() {
- return new Map();
- }
- };
-
- @NotNull
- public static CodiceGestionaleUscite.Map parseAll(@NotNull List records, @NotNull Comparto.Map comparti) {
- return CodiceGestionale.parseAll(records, CREATOR, comparti);
- }
-
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Comparto.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Comparto.java
deleted file mode 100644
index 279be55..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Comparto.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-@EqualsAndHashCode(of = {"codice"})
-public final class Comparto {
-
- public final static class Map extends AutoMap {
-
- @NotNull
- @Override
- protected String getKey(@NotNull Comparto value) {
- return value.getCodice();
- }
- }
-
- @NotNull
- @Getter
- private final String codice, nome;
-
- private Comparto(@NotNull String codice, @NotNull String nome) {
- this.codice = codice;
- this.nome = nome;
- }
-
- @NotNull
- public static Comparto parse(@NotNull CSVRecord record) {
- if (record.size() != 2) {
- throw new IllegalArgumentException("Record size != 2");
- } else {
- final String codice = record.get(0);
- final String nome = record.get(1);
-
- if (codice == null || codice.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid codice: " + codice);
- } else if (nome == null || nome.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid nome: " + nome);
- }
- return new Comparto(codice.trim(), nome.trim());
- }
- }
-
- @NotNull
- public static Map parseAll(@NotNull List records) {
- return AutoMap.parse(records, Comparto::parse, Map::new);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Comune.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Comune.java
deleted file mode 100644
index 2520883..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Comune.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-@EqualsAndHashCode(of = {"comuneId"})
-public final class Comune {
-
- public static final String COMUNE_DI = "COMUNE DI ";
-
- public static final class Map extends AutoMap {
-
- @NotNull
- @Override
- protected ComuneId getKey(@NotNull Comune value) {
- return value.getComuneId();
- }
- }
-
- @EqualsAndHashCode(of = {"codice", "provincia"})
- public static class ComuneId {
- @Getter
- private final int codice;
- @Getter
- @NotNull
- private final Provincia provincia;
-
- public ComuneId(int codice, @NotNull Provincia provincia) {
- this.codice = codice;
- this.provincia = provincia;
- }
- }
-
- @Getter
- private final ComuneId comuneId;
-
- @Getter
- @NotNull
- private final String nome;
-
-
- public Comune(ComuneId comuneId, @NotNull String nome) {
- this.comuneId = comuneId;
- this.nome = nome;
- }
-
- @NotNull
- public Provincia getProvincia() {
- return comuneId.getProvincia();
- }
-
- @NotNull
- public static Comune parse(@NotNull CSVRecord record, @NotNull Provincia.Map provincie) {
- if (record.size() != 3) {
- throw new IllegalArgumentException("Record size != 3");
- } else {
- final int codice;
- try {
- codice = Integer.parseInt(record.get(0));
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid codice: " + record.get(1), nfe);
- }
- String nome = record.get(1);
- final int provincia;
- try {
- provincia = Integer.parseInt(record.get(2));
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid provincia: " + record.get(2), nfe);
- }
-
- if (codice <= 0) {
- throw new IllegalArgumentException("Invalid codice: " + codice);
- } else if (nome == null || nome.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid nome: " + nome);
- }
- if (nome.startsWith(COMUNE_DI)) {
- nome = nome.substring(COMUNE_DI.length(), nome.length());
- }
- return new Comune(new ComuneId(codice, provincie.get(provincia)), nome.trim());
- }
- }
-
- @NotNull
- public static Comune.Map parseAll(@NotNull List records, @NotNull Provincia.Map provincie) {
- return AutoMap.parse(records, x -> parse(x, provincie), Comune.Map::new);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Ente.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Ente.java
deleted file mode 100644
index b6ef305..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Ente.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import mmauro.siopeDownloader.utils.ParseUtils;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.Contract;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-@EqualsAndHashCode(of = {"codice"})
-public class Ente {
-
- public static class Map extends AutoMap {
-
- @NotNull
- @Override
- protected String getKey(@NotNull Ente value) {
- return value.getCodice();
- }
- }
-
- @NotNull
- @Getter
- private final String codice;
- @NotNull
- @Getter
- private final Date dataInclusione;
- @Nullable
- private final Date dataEsclusione;
- @Nullable
- @Getter
- private final String codiceFiscale;
- @NotNull
- @Getter
- private final String nome;
- @NotNull
- @Getter
- private final Comune comune;
- @Nullable
- private final Integer numeroAbitanti;
- @NotNull
- @Getter
- private final Sottocomparto sottocomparto;
-
- private Ente(@NotNull String codice, @NotNull Date dataInclusione, @Nullable Date dataEsclusione, @Nullable String codiceFiscale, @NotNull String nome, @NotNull Comune comune, @Nullable Integer numeroAbitanti, @NotNull Sottocomparto sottocomparto) {
- this.codice = codice;
- this.dataInclusione = dataInclusione;
- this.dataEsclusione = dataEsclusione;
- this.codiceFiscale = codiceFiscale;
- this.nome = nome;
- this.comune = comune;
- this.numeroAbitanti = numeroAbitanti;
- this.sottocomparto = sottocomparto;
- }
-
-
- @Nullable
- @Contract(pure = true)
- public Date optDataEsclusione() {
- return dataEsclusione;
- }
-
- @Contract(pure = true)
- public boolean hasDataEsclusione() {
- return dataEsclusione != null;
- }
-
- @NotNull
- @Contract(pure = true)
- public Date getDataEsclusione() {
- if (dataEsclusione == null) {
- throw new IllegalStateException("dataEsclusione == null");
- }
- return dataEsclusione;
- }
-
- @Nullable
- @Contract(pure = true)
- public Integer optNumeroAbitanti() {
- return numeroAbitanti;
- }
-
- @Contract(pure = true)
- public boolean hasNumeroAbitanti() {
- return numeroAbitanti != null;
- }
-
- @Contract(pure = true)
- public int getNumeroAbitanti() {
- if (numeroAbitanti == null) {
- throw new IllegalStateException("numeroAbitanti == null");
- }
- return numeroAbitanti;
- }
-
- @NotNull
- public static Ente parse(@NotNull CSVRecord record, @NotNull Comune.Map comuni, @NotNull Provincia.Map provincie, @NotNull Sottocomparto.Map sottocomparti) {
- if (record.size() != 9) {
- throw new IllegalArgumentException("Record size != 9");
- } else {
- String codice = record.get(0);
-
- Date dataInclusione, dataEsclusione;
- synchronized (ParseUtils.DATE_FORMAT) {
- try {
- dataInclusione = ParseUtils.DATE_FORMAT.parse(record.get(1));
- } catch (ParseException e) {
- throw new IllegalStateException("Illegal inserimento date: " + record.get(1), e);
- }
- try {
- dataEsclusione = ParseUtils.DATE_FORMAT.parse(record.get(2));
- Calendar cal = Calendar.getInstance();
- cal.setTime(dataEsclusione);
- if (cal.get(Calendar.YEAR) == 9999 && cal.get(Calendar.MONTH) == Calendar.DECEMBER && cal.get(Calendar.DAY_OF_MONTH) == 31) {
- dataEsclusione = null;
- }
- } catch (ParseException e) {
- throw new IllegalStateException("Illegal inserimento date: " + record.get(2), e);
- }
- }
- String codiceFiscale = record.get(3);
- if(codiceFiscale.trim().isEmpty()) {
- codiceFiscale = null;
- }
- final String nome = record.get(4);
- final int codComune, codProvincia;
- try {
- codComune = Integer.parseInt(record.get(5));
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid codice comune: " + record.get(5), nfe);
- }
- try {
- codProvincia = Integer.parseInt(record.get(6));
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid codice provincia: " + record.get(6), nfe);
- }
- final Comune comune = comuni.get(new Comune.ComuneId(codComune, provincie.get(codProvincia)));
- final Integer numAbitanti;
- try {
- String str = record.get(7);
- if (str == null || str.trim().isEmpty()) {
- numAbitanti = null;
- } else {
- numAbitanti = Integer.parseInt(str);
- }
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid numAbitanti: " + record.get(7), nfe);
- }
- final Sottocomparto sottocomparto = sottocomparti.get(record.get(8));
-
- if (codice == null || codice.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid codice: " + codice);
- } else if (nome == null || nome.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid nome: " + nome);
- }
-
- return new Ente(codice, dataInclusione, dataEsclusione, codiceFiscale, nome, comune, numAbitanti, sottocomparto);
- }
- }
-
- @NotNull
- public static Ente.Map parseAll(@NotNull List records, @NotNull Comune.Map comuni, @NotNull Provincia.Map provincie, @NotNull Sottocomparto.Map sottocomparti) {
- return AutoMap.parse(records, x -> parse(x, comuni, provincie, sottocomparti), Ente.Map::new);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Provincia.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Provincia.java
deleted file mode 100644
index 4533d64..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Provincia.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-@EqualsAndHashCode(of = {"codice"})
-public final class Provincia {
- public static final class Map extends AutoMap {
-
- @NotNull
- @Override
- protected Integer getKey(@NotNull Provincia value) {
- return value.getCodice();
- }
- }
-
- @Getter
- private final int codice;
- @Getter
- @NotNull
- private final String nome;
- @Getter
- @NotNull
- private final Regione regione;
-
- private Provincia(int codice, @NotNull String nome, @NotNull Regione regione) {
- this.codice = codice;
- this.nome = nome;
- this.regione = regione;
- }
-
- @NotNull
- public static Provincia parse(@NotNull CSVRecord record, @NotNull Regione.Map regioni) {
- if (record.size() != 5) {
- throw new IllegalArgumentException("Record size != 5");
- } else {
- final int regione;
- try {
- regione = Integer.parseInt(record.get(1));
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid regione: " + record.get(1), nfe);
- }
- final int codice;
- try {
- codice = Integer.parseInt(record.get(3));
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid codice: " + record.get(3), nfe);
- }
- final String nome = record.get(4);
-
- if (codice <= 0) {
- throw new IllegalArgumentException("Invalid codice: " + codice);
- } else if (nome == null || nome.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid nome: " + nome);
- }
- return new Provincia(codice, nome.trim(), regioni.get(regione));
- }
- }
-
- @NotNull
- public static Provincia.Map parseAll(@NotNull List records, @NotNull Regione.Map regioni) {
- return AutoMap.parse(records, x -> parse(x, regioni), Provincia.Map::new);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Regione.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Regione.java
deleted file mode 100644
index 70116c1..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Regione.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-@EqualsAndHashCode(of = {"codice"})
-public final class Regione {
-
- public static final class Map extends AutoMap {
-
- @NotNull
- @Override
- protected Integer getKey(@NotNull Regione value) {
- return value.getCodice();
- }
- }
-
- @Getter
- private final int codice;
- @NotNull
- @Getter
- private final String nome;
- @NotNull
- @Getter
- private final RipartizioneGeografica ripartizioneGeografica;
-
- private Regione(int codice, @NotNull String nome, @NotNull RipartizioneGeografica ripartizioneGeografica) {
- this.codice = codice;
- this.nome = nome;
- this.ripartizioneGeografica = ripartizioneGeografica;
- }
-
- @NotNull
- public static Regione parse(@NotNull CSVRecord record, @NotNull RipartizioneGeografica.Map ripartizioniGeografiche) {
- if (record.size() != 5) {
- throw new IllegalArgumentException("Record size != 5");
- } else {
- final String ripartizioneGeografica = record.get(0);
- final int codice;
- try {
- codice = Integer.parseInt(record.get(1));
- } catch (NumberFormatException nfe) {
- throw new IllegalStateException("Invalid codice: " + record.get(1), nfe);
- }
- final String nome = record.get(2);
-
- if (codice <= 0) {
- throw new IllegalArgumentException("Invalid codice: " + codice);
- } else if (nome == null || nome.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid nome: " + nome);
- }
- return new Regione(codice, nome.trim(), ripartizioniGeografiche.get(ripartizioneGeografica));
- }
- }
-
- @NotNull
- public static Regione.Map parseAll(@NotNull List records, @NotNull RipartizioneGeografica.Map ripartizioniGeografiche) {
- return AutoMap.parse(records, x -> parse(x, ripartizioniGeografiche), Regione.Map::new);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/RipartizioneGeografica.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/RipartizioneGeografica.java
deleted file mode 100644
index 60d0600..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/RipartizioneGeografica.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-
-@EqualsAndHashCode(of = {"nome"})
-public final class RipartizioneGeografica {
-
- public final static class Map extends AutoMap {
-
- @NotNull
- @Override
- protected String getKey(@NotNull RipartizioneGeografica value) {
- return value.getNome();
- }
- }
-
- @NotNull
- @Getter
- private final String nome;
-
- private RipartizioneGeografica(@NotNull String nome) {
- this.nome = nome;
- }
-
- @NotNull
- public static RipartizioneGeografica parse(@NotNull CSVRecord record) {
- if (record.size() != 5) {
- throw new IllegalArgumentException("Record size != 5");
- } else {
- final String nome = record.get(0);
-
- if (nome == null || nome.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid nome: " + nome);
- }
- return new RipartizioneGeografica(nome.trim());
- }
- }
-
- @NotNull
- public static RipartizioneGeografica.Map parseAll(@NotNull List records) {
- return AutoMap.parse(records, RipartizioneGeografica::parse, RipartizioneGeografica.Map::new);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Sottocomparto.java b/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Sottocomparto.java
deleted file mode 100644
index 8941eaf..0000000
--- a/src/main/java/mmauro/siopeDownloader/datastruct/anagrafiche/Sottocomparto.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package mmauro.siopeDownloader.datastruct.anagrafiche;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.AutoMap;
-import org.apache.commons.csv.CSVParser;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-@EqualsAndHashCode(of = {"codice"})
-public final class Sottocomparto {
-
- public final static class Map extends AutoMap {
-
- @NotNull
- @Override
- protected String getKey(@NotNull Sottocomparto value) {
- return value.getCodice();
- }
- }
-
- @Getter
- @NotNull
- private final String codice, nome;
- @Getter
- @NotNull
- private final Comparto comparto;
-
- private Sottocomparto(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto) {
- this.codice = codice;
- this.nome = nome;
- this.comparto = comparto;
- }
-
- @NotNull
- public static Sottocomparto parse(@NotNull CSVRecord record, @NotNull Comparto.Map comparti) {
- if (record.size() != 3) {
- throw new IllegalArgumentException("Record size != 3");
- } else {
- final String codice = record.get(0);
- final String nome = record.get(1);
- final String comparto = record.get(2);
-
- if (codice == null || codice.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid codice: " + codice);
- } else if (nome == null || nome.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid nome: " + nome);
- } else if (comparto == null || comparto.trim().isEmpty()) {
- throw new IllegalArgumentException("Invalid comparto: " + comparto);
- }
- return new Sottocomparto(codice.trim(), nome.trim(), comparti.get(comparto.trim()));
- }
- }
-
- @NotNull
- public static Sottocomparto.Map parseAll(@NotNull List records, @NotNull Comparto.Map comparti) {
- return AutoMap.parse(records, x -> parse(x, comparti), Sottocomparto.Map::new);
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/download/SiopeZipDownloader.java b/src/main/java/mmauro/siopeDownloader/download/SiopeZipDownloader.java
deleted file mode 100644
index 4f9a267..0000000
--- a/src/main/java/mmauro/siopeDownloader/download/SiopeZipDownloader.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package mmauro.siopeDownloader.download;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipInputStream;
-
-public class SiopeZipDownloader {
-
- @NotNull
- private final URL url;
-
- public SiopeZipDownloader(@NotNull URL url) {
- this.url = url;
- }
-
- @NotNull
- public ZipInputStream download() throws IOException {
- final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- if (urlConnection.getResponseCode() == 200) {
- return new ZipInputStream(urlConnection.getInputStream());
- } else {
- throw new IOException("Response code: " + urlConnection.getResponseCode() + ", " + urlConnection.getResponseMessage());
- }
- }
-}
diff --git a/src/main/java/mmauro/siopeDownloader/utils/ParseUtils.java b/src/main/java/mmauro/siopeDownloader/utils/ParseUtils.java
deleted file mode 100644
index 309108e..0000000
--- a/src/main/java/mmauro/siopeDownloader/utils/ParseUtils.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package mmauro.siopeDownloader.utils;
-
-import org.apache.commons.csv.CSVFormat;
-
-import java.text.SimpleDateFormat;
-
-public final class ParseUtils {
- private ParseUtils() {
- throw new IllegalStateException();
- }
-
- public static final CSVFormat CSV_FORMAT = CSVFormat.newFormat(',')
- .withIgnoreEmptyLines()
- .withQuote('"');
-
-
- public final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
-}
diff --git a/src/main/java/mmauro/siopeDownloader/utils/ReaderUtils.java b/src/main/java/mmauro/siopeDownloader/utils/ReaderUtils.java
deleted file mode 100644
index 636f24d..0000000
--- a/src/main/java/mmauro/siopeDownloader/utils/ReaderUtils.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package mmauro.siopeDownloader.utils;
-
-import org.jetbrains.annotations.NotNull;
-import sun.misc.IOUtils;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.util.Scanner;
-
-public final class ReaderUtils {
-
- private ReaderUtils() {
- throw new IllegalStateException();
- }
-
- @NotNull
- public static String readAll(@NotNull final Reader reader) throws IOException {
- final char[] buffer = new char[1024];
- final StringBuilder out = new StringBuilder();
- while (true) {
- int rsz = reader.read(buffer, 0, buffer.length);
- if (rsz < 0)
- break;
- out.append(buffer, 0, rsz);
- }
- return out.toString();
- }
-
-
-}
diff --git a/src/main/java/mmauro/siopeDownloader/utils/URLUtils.java b/src/main/java/mmauro/siopeDownloader/utils/URLUtils.java
deleted file mode 100644
index 7b53faf..0000000
--- a/src/main/java/mmauro/siopeDownloader/utils/URLUtils.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package mmauro.siopeDownloader.utils;
-
-public final class URLUtils {
- private URLUtils() {
- throw new IllegalStateException();
- }
-
- public static final String SIOPE_WEBSITE = "https://www.siope.it";
-}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/AutoMap.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/AutoMap.java
new file mode 100644
index 0000000..0538ccf
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/AutoMap.java
@@ -0,0 +1,137 @@
+package org.github.mmauro94.siopeDownloader.datastruct;
+
+import org.github.mmauro94.siopeDownloader.utils.CSVRecordParser;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+public abstract class AutoMap implements Collection {
+
+ public interface AutoMapCreator> {
+ T create();
+ }
+
+ @NotNull
+ private final HashMap map = new HashMap<>();
+
+ public AutoMap() {
+ }
+
+ @NotNull
+ protected abstract K getKey(@NotNull V value);
+
+ @NotNull
+ public V get(@NotNull K key) {
+ if (!map.containsKey(key)) {
+ throw new IllegalStateException("Value with key " + key + " not found");
+ }
+ return map.get(key);
+ }
+
+ public void put(@NotNull V value) {
+ map.put(getKey(value), value);
+ }
+
+ public boolean hasKey(@NotNull K key) {
+ return map.containsKey(key);
+ }
+
+ public boolean hasValue(@NotNull V key) {
+ return map.containsValue(key);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return map.containsValue(o);
+ }
+
+ @NotNull
+ @Override
+ public Iterator iterator() {
+ return map.values().iterator();
+ }
+
+ @NotNull
+ @Override
+ public Object[] toArray() {
+ return map.values().toArray();
+ }
+
+ @NotNull
+ @Override
+ public T[] toArray(@NotNull T[] a) {
+ return map.values().toArray(a);
+ }
+
+ @Override
+ public boolean add(V v) {
+ if (hasValue(v)) {
+ put(v);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return map.values().remove(o);
+ }
+
+ @Override
+ public boolean containsAll(@NotNull Collection> c) {
+ return map.values().containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(@NotNull Collection extends V> c) {
+ boolean changed = false;
+ for (V v : c) {
+ changed |= add(v);
+ }
+ return changed;
+ }
+
+ @Override
+ public boolean removeAll(@NotNull Collection> c) {
+ return map.values().removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(@NotNull Collection> c) {
+ return map.values().retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ map.clear();
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ public static > T parse(@NotNull List records, @NotNull CSVRecordParser recordParser, @NotNull AutoMapCreator mapCreator) {
+ T map = mapCreator.create();
+ for (CSVRecord record : records) {
+ map.put(recordParser.parse(record));
+ }
+ return map;
+ }
+
+ public static > T parse(@NotNull CSVParser parser, @NotNull CSVRecordParser recordParser, @NotNull AutoMapCreator mapCreator) throws IOException {
+ return parse(parser.getRecords(), recordParser, mapCreator);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Anagrafiche.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Anagrafiche.java
new file mode 100644
index 0000000..eb98ed9
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Anagrafiche.java
@@ -0,0 +1,128 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.download.SiopeZipDownloader;
+import org.github.mmauro94.siopeDownloader.utils.ParseUtils;
+import org.github.mmauro94.siopeDownloader.utils.ReaderUtils;
+import org.github.mmauro94.siopeDownloader.utils.URLUtils;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class Anagrafiche {
+
+ public static final String FILE_LOCATION = "/Siope2Web/documenti/siope2/open/last/SIOPE_ANAGRAFICHE.zip";
+
+ @NotNull
+ @Getter
+ private final Comparto.Map comparti;
+ @NotNull
+ @Getter
+ private final Sottocomparto.Map sottocomparti;
+ @NotNull
+ @Getter
+ private final RipartizioneGeografica.Map ripartizioniGeografiche;
+ @NotNull
+ @Getter
+ private final Regione.Map regioni;
+ @NotNull
+ @Getter
+ private final Provincia.Map provincie;
+ @NotNull
+ @Getter
+ private final Comune.Map comuni;
+ @NotNull
+ @Getter
+ private final Ente.Map enti;
+ @NotNull
+ @Getter
+ private final CodiceGestionaleEntrate.Map codiciGestionaliEntrate;
+ @NotNull
+ @Getter
+ private final CodiceGestionaleUscite.Map codiciGestionaliUscite;
+
+ private Anagrafiche(@NotNull Comparto.Map comparti, @NotNull Sottocomparto.Map sottocomparti, @NotNull RipartizioneGeografica.Map ripartizioniGeografiche, @NotNull Regione.Map regioni, @NotNull Provincia.Map provincie, @NotNull Comune.Map comuni, @NotNull Ente.Map enti, @NotNull CodiceGestionaleEntrate.Map codiciGestionaliEntrate, @NotNull CodiceGestionaleUscite.Map codiciGestionaliUscite) {
+ this.comparti = comparti;
+ this.sottocomparti = sottocomparti;
+ this.ripartizioniGeografiche = ripartizioniGeografiche;
+ this.regioni = regioni;
+ this.provincie = provincie;
+ this.comuni = comuni;
+ this.enti = enti;
+ this.codiciGestionaliEntrate = codiciGestionaliEntrate;
+ this.codiciGestionaliUscite = codiciGestionaliUscite;
+ }
+
+ @NotNull
+ public static Anagrafiche downloadAnagrafiche() throws IOException {
+ ZipInputStream download = new SiopeZipDownloader(new URL(URLUtils.SIOPE_WEBSITE + FILE_LOCATION)).download();
+ ZipEntry entry;
+
+
+ List compartiRecords = null, sottocompartiRecords = null, regProvRecords = null, comuniRecords = null, entiRecords = null, codGestEntRecords = null, codGestUscRecords = null;
+ while ((entry = download.getNextEntry()) != null) {
+ final List records = CSVParser.parse(ReaderUtils.readAll(new InputStreamReader(download)), ParseUtils.CSV_FORMAT).getRecords();
+
+ switch (entry.getName().substring(0, entry.getName().indexOf('.'))) {
+ case "ANAG_COMPARTI":
+ compartiRecords = records;
+ break;
+ case "ANAG_SOTTOCOMPARTI":
+ sottocompartiRecords = records;
+ break;
+ case "ANAG_REG_PROV":
+ regProvRecords = records;
+ break;
+ case "ANAG_COMUNI":
+ case "ANAGRAFE_COMUNI":
+ comuniRecords = records;
+ break;
+ case "ANAG_ENTI_SIOPE":
+ entiRecords = records;
+ break;
+ case "ANAG_CODGEST_ENTRATE":
+ codGestEntRecords = records;
+ break;
+ case "ANAG_CODGEST_USCITE":
+ codGestUscRecords = records;
+ continue;
+ default:
+ throw new IllegalStateException("Unexpected file: " + entry.getName());
+ }
+ }
+ if (compartiRecords == null) {
+ throw new IllegalStateException("File ANAG_COMPARTI not found");
+ } else if (sottocompartiRecords == null) {
+ throw new IllegalStateException("File ANAG_SOTTOCOMPARTI not found");
+ } else if (regProvRecords == null) {
+ throw new IllegalStateException("File ANAG_REG_PROV not found");
+ } else if (comuniRecords == null) {
+ throw new IllegalStateException("File ANAGRAFE_COMUNI/ANAG_COMUNI not found");
+ } else if (entiRecords == null) {
+ throw new IllegalStateException("File ANAG_ENTI_SIOPE not found");
+ } else if (codGestEntRecords == null) {
+ throw new IllegalStateException("File ANAG_CODGEST_ENTRATE not found");
+ } else if (codGestUscRecords == null) {
+ throw new IllegalStateException("File ANAG_CODGEST_USCITE not found");
+ }
+
+ final Comparto.Map comparti = Comparto.parseAll(compartiRecords);
+ final Sottocomparto.Map sottocomparti = Sottocomparto.parseAll(sottocompartiRecords, comparti);
+ final RipartizioneGeografica.Map ripartizioniGeografiche = RipartizioneGeografica.parseAll(regProvRecords);
+ final Regione.Map regioni = Regione.parseAll(regProvRecords, ripartizioniGeografiche);
+ final Provincia.Map provincie = Provincia.parseAll(regProvRecords, regioni);
+ final Comune.Map comuni = Comune.parseAll(comuniRecords, provincie);
+ final Ente.Map enti = Ente.parseAll(entiRecords, comuni, provincie, sottocomparti);
+ final CodiceGestionaleEntrate.Map codiciGestionaliEntrate = CodiceGestionaleEntrate.parseAll(codGestEntRecords, comparti);
+ final CodiceGestionaleUscite.Map codiciGestionaliUscite = CodiceGestionaleUscite.parseAll(codGestUscRecords, comparti);
+
+ return new Anagrafiche(comparti, sottocomparti, ripartizioniGeografiche, regioni, provincie, comuni, enti, codiciGestionaliEntrate, codiciGestionaliUscite);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionale.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionale.java
new file mode 100644
index 0000000..89b53a4
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionale.java
@@ -0,0 +1,92 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.github.mmauro94.siopeDownloader.utils.ParseUtils;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+@EqualsAndHashCode(of = {"codice"})
+public abstract class CodiceGestionale {
+
+ public static abstract class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected String getKey(@NotNull CodiceGestionale value) {
+ return value.getCodice();
+ }
+ }
+
+ public interface Creator> {
+ T create(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita);
+
+ M createMap();
+ }
+
+ @NotNull
+ @Getter
+ private final String codice;
+ @NotNull
+ @Getter
+ private final String nome;
+ @NotNull
+ @Getter
+ private final Comparto comparto;
+ @NotNull
+ @Getter
+ private final Date inizioValidita;
+ @Nullable
+ @Getter
+ private final Date fineValidita;
+
+ protected CodiceGestionale(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
+ this.codice = codice;
+ this.nome = nome;
+ this.comparto = comparto;
+ this.inizioValidita = inizioValidita;
+ this.fineValidita = fineValidita;
+ }
+
+ @NotNull
+ public static T parse(@NotNull CSVRecord record, @NotNull Creator creator, @NotNull Comparto.Map comparti) {
+ if (record.size() != 5) {
+ throw new IllegalArgumentException("Record size != 5");
+ } else {
+ final String codice = record.get(0);
+ final String codiceCategoriaComparto = record.get(1);
+ final String nome = record.get(2);
+ Date dataInizio, dataFine;
+ synchronized (ParseUtils.DATE_FORMAT) {
+ try {
+ dataInizio = ParseUtils.DATE_FORMAT.parse(record.get(3));
+ } catch (ParseException e) {
+ throw new IllegalStateException("Illega l inizio validità date: " + record.get(1), e);
+ }
+ try {
+ dataFine = ParseUtils.DATE_FORMAT.parse(record.get(4));
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dataFine);
+ if (cal.get(Calendar.YEAR) == 9999 && cal.get(Calendar.MONTH) == Calendar.DECEMBER && cal.get(Calendar.DAY_OF_MONTH) == 31) {
+ dataFine = null;
+ }
+ } catch (ParseException e) {
+ throw new IllegalStateException("Illegal inserimento date: " + record.get(2), e);
+ }
+ }
+ return creator.create(codice, nome, comparti.get(codiceCategoriaComparto), dataInizio, dataFine);
+ }
+ }
+
+ @NotNull
+ public static > M parseAll(@NotNull List records, @NotNull Creator creator, @NotNull Comparto.Map comparti) {
+ return AutoMap.parse(records, x -> parse(x, creator, comparti), creator::createMap);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleEntrate.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleEntrate.java
new file mode 100644
index 0000000..ad67bfa
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleEntrate.java
@@ -0,0 +1,37 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+import java.util.List;
+
+public class CodiceGestionaleEntrate extends CodiceGestionale {
+
+ public static class Map extends CodiceGestionale.Map {
+
+ }
+
+ protected CodiceGestionaleEntrate(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
+ super(codice, nome, comparto, inizioValidita, fineValidita);
+ }
+
+ protected static final CodiceGestionale.Creator CREATOR = new CodiceGestionale.Creator() {
+ @Override
+ public CodiceGestionaleEntrate create(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
+ return new CodiceGestionaleEntrate(codice, nome, comparto, inizioValidita, fineValidita);
+ }
+
+ @Override
+ public Map createMap() {
+ return new Map();
+ }
+ };
+
+ @NotNull
+ public static CodiceGestionaleEntrate.Map parseAll(@NotNull List records, @NotNull Comparto.Map comparti) {
+ return parseAll(records, CREATOR, comparti);
+ }
+
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleUscite.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleUscite.java
new file mode 100644
index 0000000..1aade65
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/CodiceGestionaleUscite.java
@@ -0,0 +1,37 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+import java.util.List;
+
+public class CodiceGestionaleUscite extends CodiceGestionale {
+
+ public static class Map extends CodiceGestionale.Map {
+
+ }
+
+ protected CodiceGestionaleUscite(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
+ super(codice, nome, comparto, inizioValidita, fineValidita);
+ }
+
+ protected static final Creator CREATOR = new Creator() {
+ @Override
+ public CodiceGestionaleUscite create(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto, @NotNull Date inizioValidita, @Nullable Date fineValidita) {
+ return new CodiceGestionaleUscite(codice, nome, comparto, inizioValidita, fineValidita);
+ }
+
+ @Override
+ public Map createMap() {
+ return new Map();
+ }
+ };
+
+ @NotNull
+ public static CodiceGestionaleUscite.Map parseAll(@NotNull List records, @NotNull Comparto.Map comparti) {
+ return parseAll(records, CREATOR, comparti);
+ }
+
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Comparto.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Comparto.java
new file mode 100644
index 0000000..9952220
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Comparto.java
@@ -0,0 +1,53 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+@EqualsAndHashCode(of = {"codice"})
+public final class Comparto {
+
+ public final static class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected String getKey(@NotNull Comparto value) {
+ return value.getCodice();
+ }
+ }
+
+ @NotNull
+ @Getter
+ private final String codice, nome;
+
+ private Comparto(@NotNull String codice, @NotNull String nome) {
+ this.codice = codice;
+ this.nome = nome;
+ }
+
+ @NotNull
+ public static Comparto parse(@NotNull CSVRecord record) {
+ if (record.size() != 2) {
+ throw new IllegalArgumentException("Record size != 2");
+ } else {
+ final String codice = record.get(0);
+ final String nome = record.get(1);
+
+ if (codice == null || codice.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid codice: " + codice);
+ } else if (nome == null || nome.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid nome: " + nome);
+ }
+ return new Comparto(codice.trim(), nome.trim());
+ }
+ }
+
+ @NotNull
+ public static Map parseAll(@NotNull List records) {
+ return AutoMap.parse(records, Comparto::parse, Map::new);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Comune.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Comune.java
new file mode 100644
index 0000000..5db2fb4
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Comune.java
@@ -0,0 +1,92 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+@EqualsAndHashCode(of = {"comuneId"})
+public final class Comune {
+
+ public static final String COMUNE_DI = "COMUNE DI ";
+
+ public static final class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected ComuneId getKey(@NotNull Comune value) {
+ return value.getComuneId();
+ }
+ }
+
+ @EqualsAndHashCode(of = {"codice", "provincia"})
+ public static class ComuneId {
+ @Getter
+ private final int codice;
+ @Getter
+ @NotNull
+ private final Provincia provincia;
+
+ public ComuneId(int codice, @NotNull Provincia provincia) {
+ this.codice = codice;
+ this.provincia = provincia;
+ }
+ }
+
+ @Getter
+ private final ComuneId comuneId;
+
+ @Getter
+ @NotNull
+ private final String nome;
+
+
+ public Comune(ComuneId comuneId, @NotNull String nome) {
+ this.comuneId = comuneId;
+ this.nome = nome;
+ }
+
+ @NotNull
+ public Provincia getProvincia() {
+ return comuneId.getProvincia();
+ }
+
+ @NotNull
+ public static Comune parse(@NotNull CSVRecord record, @NotNull Provincia.Map provincie) {
+ if (record.size() != 3) {
+ throw new IllegalArgumentException("Record size != 3");
+ } else {
+ final int codice;
+ try {
+ codice = Integer.parseInt(record.get(0));
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid codice: " + record.get(1), nfe);
+ }
+ String nome = record.get(1);
+ final int provincia;
+ try {
+ provincia = Integer.parseInt(record.get(2));
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid provincia: " + record.get(2), nfe);
+ }
+
+ if (codice <= 0) {
+ throw new IllegalArgumentException("Invalid codice: " + codice);
+ } else if (nome == null || nome.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid nome: " + nome);
+ }
+ if (nome.startsWith(COMUNE_DI)) {
+ nome = nome.substring(COMUNE_DI.length(), nome.length());
+ }
+ return new Comune(new ComuneId(codice, provincie.get(provincia)), nome.trim());
+ }
+ }
+
+ @NotNull
+ public static Comune.Map parseAll(@NotNull List records, @NotNull Provincia.Map provincie) {
+ return AutoMap.parse(records, x -> parse(x, provincie), Comune.Map::new);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Ente.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Ente.java
new file mode 100644
index 0000000..a234c8d
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Ente.java
@@ -0,0 +1,172 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.github.mmauro94.siopeDownloader.utils.ParseUtils;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+@EqualsAndHashCode(of = {"codice"})
+public class Ente {
+
+ public static class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected String getKey(@NotNull Ente value) {
+ return value.getCodice();
+ }
+ }
+
+ @NotNull
+ @Getter
+ private final String codice;
+ @NotNull
+ @Getter
+ private final Date dataInclusione;
+ @Nullable
+ private final Date dataEsclusione;
+ @Nullable
+ @Getter
+ private final String codiceFiscale;
+ @NotNull
+ @Getter
+ private final String nome;
+ @NotNull
+ @Getter
+ private final Comune comune;
+ @Nullable
+ private final Integer numeroAbitanti;
+ @NotNull
+ @Getter
+ private final Sottocomparto sottocomparto;
+
+ private Ente(@NotNull String codice, @NotNull Date dataInclusione, @Nullable Date dataEsclusione, @Nullable String codiceFiscale, @NotNull String nome, @NotNull Comune comune, @Nullable Integer numeroAbitanti, @NotNull Sottocomparto sottocomparto) {
+ this.codice = codice;
+ this.dataInclusione = dataInclusione;
+ this.dataEsclusione = dataEsclusione;
+ this.codiceFiscale = codiceFiscale;
+ this.nome = nome;
+ this.comune = comune;
+ this.numeroAbitanti = numeroAbitanti;
+ this.sottocomparto = sottocomparto;
+ }
+
+
+ @Nullable
+ @Contract(pure = true)
+ public Date optDataEsclusione() {
+ return dataEsclusione;
+ }
+
+ @Contract(pure = true)
+ public boolean hasDataEsclusione() {
+ return dataEsclusione != null;
+ }
+
+ @NotNull
+ @Contract(pure = true)
+ public Date getDataEsclusione() {
+ if (dataEsclusione == null) {
+ throw new IllegalStateException("dataEsclusione == null");
+ }
+ return dataEsclusione;
+ }
+
+ @Nullable
+ @Contract(pure = true)
+ public Integer optNumeroAbitanti() {
+ return numeroAbitanti;
+ }
+
+ @Contract(pure = true)
+ public boolean hasNumeroAbitanti() {
+ return numeroAbitanti != null;
+ }
+
+ @Contract(pure = true)
+ public int getNumeroAbitanti() {
+ if (numeroAbitanti == null) {
+ throw new IllegalStateException("numeroAbitanti == null");
+ }
+ return numeroAbitanti;
+ }
+
+ @NotNull
+ public static Ente parse(@NotNull CSVRecord record, @NotNull Comune.Map comuni, @NotNull Provincia.Map provincie, @NotNull Sottocomparto.Map sottocomparti) {
+ if (record.size() != 9) {
+ throw new IllegalArgumentException("Record size != 9");
+ } else {
+ String codice = record.get(0);
+
+ Date dataInclusione, dataEsclusione;
+ synchronized (ParseUtils.DATE_FORMAT) {
+ try {
+ dataInclusione = ParseUtils.DATE_FORMAT.parse(record.get(1));
+ } catch (ParseException e) {
+ throw new IllegalStateException("Illegal inserimento date: " + record.get(1), e);
+ }
+ try {
+ dataEsclusione = ParseUtils.DATE_FORMAT.parse(record.get(2));
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dataEsclusione);
+ if (cal.get(Calendar.YEAR) == 9999 && cal.get(Calendar.MONTH) == Calendar.DECEMBER && cal.get(Calendar.DAY_OF_MONTH) == 31) {
+ dataEsclusione = null;
+ }
+ } catch (ParseException e) {
+ throw new IllegalStateException("Illegal inserimento date: " + record.get(2), e);
+ }
+ }
+ String codiceFiscale = record.get(3);
+ if (codiceFiscale.trim().isEmpty()) {
+ codiceFiscale = null;
+ }
+ final String nome = record.get(4);
+ final int codComune, codProvincia;
+ try {
+ codComune = Integer.parseInt(record.get(5));
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid codice comune: " + record.get(5), nfe);
+ }
+ try {
+ codProvincia = Integer.parseInt(record.get(6));
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid codice provincia: " + record.get(6), nfe);
+ }
+ final Comune comune = comuni.get(new Comune.ComuneId(codComune, provincie.get(codProvincia)));
+ final Integer numAbitanti;
+ try {
+ String str = record.get(7);
+ if (str == null || str.trim().isEmpty()) {
+ numAbitanti = null;
+ } else {
+ numAbitanti = Integer.parseInt(str);
+ }
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid numAbitanti: " + record.get(7), nfe);
+ }
+ final Sottocomparto sottocomparto = sottocomparti.get(record.get(8));
+
+ if (codice == null || codice.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid codice: " + codice);
+ } else if (nome == null || nome.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid nome: " + nome);
+ }
+
+ return new Ente(codice, dataInclusione, dataEsclusione, codiceFiscale, nome, comune, numAbitanti, sottocomparto);
+ }
+ }
+
+ @NotNull
+ public static Ente.Map parseAll(@NotNull List records, @NotNull Comune.Map comuni, @NotNull Provincia.Map provincie, @NotNull Sottocomparto.Map sottocomparti) {
+ return AutoMap.parse(records, x -> parse(x, comuni, provincie, sottocomparti), Ente.Map::new);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Provincia.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Provincia.java
new file mode 100644
index 0000000..fabb408
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Provincia.java
@@ -0,0 +1,69 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+@EqualsAndHashCode(of = {"codice"})
+public final class Provincia {
+ public static final class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected Integer getKey(@NotNull Provincia value) {
+ return value.getCodice();
+ }
+ }
+
+ @Getter
+ private final int codice;
+ @Getter
+ @NotNull
+ private final String nome;
+ @Getter
+ @NotNull
+ private final Regione regione;
+
+ private Provincia(int codice, @NotNull String nome, @NotNull Regione regione) {
+ this.codice = codice;
+ this.nome = nome;
+ this.regione = regione;
+ }
+
+ @NotNull
+ public static Provincia parse(@NotNull CSVRecord record, @NotNull Regione.Map regioni) {
+ if (record.size() != 5) {
+ throw new IllegalArgumentException("Record size != 5");
+ } else {
+ final int regione;
+ try {
+ regione = Integer.parseInt(record.get(1));
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid regione: " + record.get(1), nfe);
+ }
+ final int codice;
+ try {
+ codice = Integer.parseInt(record.get(3));
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid codice: " + record.get(3), nfe);
+ }
+ final String nome = record.get(4);
+
+ if (codice <= 0) {
+ throw new IllegalArgumentException("Invalid codice: " + codice);
+ } else if (nome == null || nome.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid nome: " + nome);
+ }
+ return new Provincia(codice, nome.trim(), regioni.get(regione));
+ }
+ }
+
+ @NotNull
+ public static Provincia.Map parseAll(@NotNull List records, @NotNull Regione.Map regioni) {
+ return AutoMap.parse(records, x -> parse(x, regioni), Provincia.Map::new);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Regione.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Regione.java
new file mode 100644
index 0000000..60b86d0
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Regione.java
@@ -0,0 +1,65 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+@EqualsAndHashCode(of = {"codice"})
+public final class Regione {
+
+ public static final class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected Integer getKey(@NotNull Regione value) {
+ return value.getCodice();
+ }
+ }
+
+ @Getter
+ private final int codice;
+ @NotNull
+ @Getter
+ private final String nome;
+ @NotNull
+ @Getter
+ private final RipartizioneGeografica ripartizioneGeografica;
+
+ private Regione(int codice, @NotNull String nome, @NotNull RipartizioneGeografica ripartizioneGeografica) {
+ this.codice = codice;
+ this.nome = nome;
+ this.ripartizioneGeografica = ripartizioneGeografica;
+ }
+
+ @NotNull
+ public static Regione parse(@NotNull CSVRecord record, @NotNull RipartizioneGeografica.Map ripartizioniGeografiche) {
+ if (record.size() != 5) {
+ throw new IllegalArgumentException("Record size != 5");
+ } else {
+ final String ripartizioneGeografica = record.get(0);
+ final int codice;
+ try {
+ codice = Integer.parseInt(record.get(1));
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException("Invalid codice: " + record.get(1), nfe);
+ }
+ final String nome = record.get(2);
+
+ if (codice <= 0) {
+ throw new IllegalArgumentException("Invalid codice: " + codice);
+ } else if (nome == null || nome.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid nome: " + nome);
+ }
+ return new Regione(codice, nome.trim(), ripartizioniGeografiche.get(ripartizioneGeografica));
+ }
+ }
+
+ @NotNull
+ public static Regione.Map parseAll(@NotNull List records, @NotNull RipartizioneGeografica.Map ripartizioniGeografiche) {
+ return AutoMap.parse(records, x -> parse(x, ripartizioniGeografiche), Regione.Map::new);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/RipartizioneGeografica.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/RipartizioneGeografica.java
new file mode 100644
index 0000000..2624e7b
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/RipartizioneGeografica.java
@@ -0,0 +1,50 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+
+@EqualsAndHashCode(of = {"nome"})
+public final class RipartizioneGeografica {
+
+ public final static class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected String getKey(@NotNull RipartizioneGeografica value) {
+ return value.getNome();
+ }
+ }
+
+ @NotNull
+ @Getter
+ private final String nome;
+
+ private RipartizioneGeografica(@NotNull String nome) {
+ this.nome = nome;
+ }
+
+ @NotNull
+ public static RipartizioneGeografica parse(@NotNull CSVRecord record) {
+ if (record.size() != 5) {
+ throw new IllegalArgumentException("Record size != 5");
+ } else {
+ final String nome = record.get(0);
+
+ if (nome == null || nome.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid nome: " + nome);
+ }
+ return new RipartizioneGeografica(nome.trim());
+ }
+ }
+
+ @NotNull
+ public static RipartizioneGeografica.Map parseAll(@NotNull List records) {
+ return AutoMap.parse(records, RipartizioneGeografica::parse, RipartizioneGeografica.Map::new);
+ }
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Sottocomparto.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Sottocomparto.java
new file mode 100644
index 0000000..a557a28
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/anagrafiche/Sottocomparto.java
@@ -0,0 +1,60 @@
+package org.github.mmauro94.siopeDownloader.datastruct.anagrafiche;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import org.github.mmauro94.siopeDownloader.datastruct.AutoMap;
+import org.apache.commons.csv.CSVRecord;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+@EqualsAndHashCode(of = {"codice"})
+public final class Sottocomparto {
+
+ public final static class Map extends AutoMap {
+
+ @NotNull
+ @Override
+ protected String getKey(@NotNull Sottocomparto value) {
+ return value.getCodice();
+ }
+ }
+
+ @Getter
+ @NotNull
+ private final String codice, nome;
+ @Getter
+ @NotNull
+ private final Comparto comparto;
+
+ private Sottocomparto(@NotNull String codice, @NotNull String nome, @NotNull Comparto comparto) {
+ this.codice = codice;
+ this.nome = nome;
+ this.comparto = comparto;
+ }
+
+ @NotNull
+ public static Sottocomparto parse(@NotNull CSVRecord record, @NotNull Comparto.Map comparti) {
+ if (record.size() != 3) {
+ throw new IllegalArgumentException("Record size != 3");
+ } else {
+ final String codice = record.get(0);
+ final String nome = record.get(1);
+ final String comparto = record.get(2);
+
+ if (codice == null || codice.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid codice: " + codice);
+ } else if (nome == null || nome.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid nome: " + nome);
+ } else if (comparto == null || comparto.trim().isEmpty()) {
+ throw new IllegalArgumentException("Invalid comparto: " + comparto);
+ }
+ return new Sottocomparto(codice.trim(), nome.trim(), comparti.get(comparto.trim()));
+ }
+ }
+
+ @NotNull
+ public static Sottocomparto.Map parseAll(@NotNull List records, @NotNull Comparto.Map comparti) {
+ return AutoMap.parse(records, x -> parse(x, comparti), Sottocomparto.Map::new);
+ }
+}
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Entrata.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Entrata.java
similarity index 73%
rename from src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Entrata.java
rename to src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Entrata.java
index bd395e4..7bd8070 100644
--- a/src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Entrata.java
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Entrata.java
@@ -1,8 +1,8 @@
-package mmauro.siopeDownloader.datastruct.operazioni;
+package org.github.mmauro94.siopeDownloader.datastruct.operazioni;
-import mmauro.siopeDownloader.datastruct.anagrafiche.Anagrafiche;
-import mmauro.siopeDownloader.datastruct.anagrafiche.CodiceGestionaleEntrate;
-import mmauro.siopeDownloader.datastruct.anagrafiche.Ente;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.Anagrafiche;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.CodiceGestionaleEntrate;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.Ente;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Operazione.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Operazione.java
similarity index 85%
rename from src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Operazione.java
rename to src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Operazione.java
index aa35272..af12bd2 100644
--- a/src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Operazione.java
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Operazione.java
@@ -1,12 +1,12 @@
-package mmauro.siopeDownloader.datastruct.operazioni;
+package org.github.mmauro94.siopeDownloader.datastruct.operazioni;
import lombok.Getter;
-import mmauro.siopeDownloader.datastruct.anagrafiche.Anagrafiche;
-import mmauro.siopeDownloader.datastruct.anagrafiche.CodiceGestionale;
-import mmauro.siopeDownloader.datastruct.anagrafiche.Ente;
-import mmauro.siopeDownloader.download.SiopeZipDownloader;
-import mmauro.siopeDownloader.utils.ParseUtils;
-import mmauro.siopeDownloader.utils.URLUtils;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.Anagrafiche;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.CodiceGestionale;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.Ente;
+import org.github.mmauro94.siopeDownloader.download.SiopeZipDownloader;
+import org.github.mmauro94.siopeDownloader.utils.ParseUtils;
+import org.github.mmauro94.siopeDownloader.utils.URLUtils;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.jetbrains.annotations.NotNull;
diff --git a/src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Uscita.java b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Uscita.java
similarity index 69%
rename from src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Uscita.java
rename to src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Uscita.java
index 96475ee..3894624 100644
--- a/src/main/java/mmauro/siopeDownloader/datastruct/operazioni/Uscita.java
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/datastruct/operazioni/Uscita.java
@@ -1,19 +1,13 @@
-package mmauro.siopeDownloader.datastruct.operazioni;
+package org.github.mmauro94.siopeDownloader.datastruct.operazioni;
-import mmauro.siopeDownloader.datastruct.anagrafiche.Anagrafiche;
-import mmauro.siopeDownloader.datastruct.anagrafiche.CodiceGestionaleUscite;
-import mmauro.siopeDownloader.datastruct.anagrafiche.Ente;
-import mmauro.siopeDownloader.datastruct.anagrafiche.Provincia;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.Anagrafiche;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.CodiceGestionaleUscite;
+import org.github.mmauro94.siopeDownloader.datastruct.anagrafiche.Ente;
import org.apache.commons.csv.CSVRecord;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
public final class Uscita extends Operazione {
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/download/SiopeZipDownloader.java b/src/main/java/org/github/mmauro94/siopeDownloader/download/SiopeZipDownloader.java
new file mode 100644
index 0000000..6162ac3
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/download/SiopeZipDownloader.java
@@ -0,0 +1,28 @@
+package org.github.mmauro94.siopeDownloader.download;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.zip.ZipInputStream;
+
+public class SiopeZipDownloader {
+
+ @NotNull
+ private final URL url;
+
+ public SiopeZipDownloader(@NotNull URL url) {
+ this.url = url;
+ }
+
+ @NotNull
+ public ZipInputStream download() throws IOException {
+ final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ if (urlConnection.getResponseCode() == 200) {
+ return new ZipInputStream(urlConnection.getInputStream());
+ } else {
+ throw new IOException("Response code: " + urlConnection.getResponseCode() + ", " + urlConnection.getResponseMessage());
+ }
+ }
+}
diff --git a/src/main/java/mmauro/siopeDownloader/utils/CSVRecordParser.java b/src/main/java/org/github/mmauro94/siopeDownloader/utils/CSVRecordParser.java
similarity index 58%
rename from src/main/java/mmauro/siopeDownloader/utils/CSVRecordParser.java
rename to src/main/java/org/github/mmauro94/siopeDownloader/utils/CSVRecordParser.java
index e13f7da..a826de5 100644
--- a/src/main/java/mmauro/siopeDownloader/utils/CSVRecordParser.java
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/utils/CSVRecordParser.java
@@ -1,8 +1,8 @@
-package mmauro.siopeDownloader.utils;
+package org.github.mmauro94.siopeDownloader.utils;
import org.apache.commons.csv.CSVRecord;
import org.jetbrains.annotations.NotNull;
public interface CSVRecordParser {
- T parse(@NotNull CSVRecord record);
+ T parse(@NotNull CSVRecord record);
}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/utils/ParseUtils.java b/src/main/java/org/github/mmauro94/siopeDownloader/utils/ParseUtils.java
new file mode 100644
index 0000000..619158d
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/utils/ParseUtils.java
@@ -0,0 +1,18 @@
+package org.github.mmauro94.siopeDownloader.utils;
+
+import org.apache.commons.csv.CSVFormat;
+
+import java.text.SimpleDateFormat;
+
+public final class ParseUtils {
+ private ParseUtils() {
+ throw new IllegalStateException();
+ }
+
+ public static final CSVFormat CSV_FORMAT = CSVFormat.newFormat(',')
+ .withIgnoreEmptyLines()
+ .withQuote('"');
+
+
+ public final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/utils/ReaderUtils.java b/src/main/java/org/github/mmauro94/siopeDownloader/utils/ReaderUtils.java
new file mode 100644
index 0000000..129da38
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/utils/ReaderUtils.java
@@ -0,0 +1,28 @@
+package org.github.mmauro94.siopeDownloader.utils;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.io.Reader;
+
+public final class ReaderUtils {
+
+ private ReaderUtils() {
+ throw new IllegalStateException();
+ }
+
+ @NotNull
+ public static String readAll(@NotNull final Reader reader) throws IOException {
+ final char[] buffer = new char[1024];
+ final StringBuilder out = new StringBuilder();
+ while (true) {
+ int rsz = reader.read(buffer, 0, buffer.length);
+ if (rsz < 0)
+ break;
+ out.append(buffer, 0, rsz);
+ }
+ return out.toString();
+ }
+
+
+}
diff --git a/src/main/java/org/github/mmauro94/siopeDownloader/utils/URLUtils.java b/src/main/java/org/github/mmauro94/siopeDownloader/utils/URLUtils.java
new file mode 100644
index 0000000..2fc592b
--- /dev/null
+++ b/src/main/java/org/github/mmauro94/siopeDownloader/utils/URLUtils.java
@@ -0,0 +1,9 @@
+package org.github.mmauro94.siopeDownloader.utils;
+
+public final class URLUtils {
+ private URLUtils() {
+ throw new IllegalStateException();
+ }
+
+ public static final String SIOPE_WEBSITE = "https://www.siope.it";
+}