Commit dbcdb668 by Patryk Czarnik

Przykład Waluty

parent 6d6ce9c0
...@@ -14,4 +14,22 @@ ...@@ -14,4 +14,22 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project> </project>
\ No newline at end of file
package waluty;
public interface Pobieranie {
/** Pobiera tabelę z bieżącymi kursami walut.
* Zwraca null w przypadku błędów.
*/
Tabela pobierzBiezaceKursy();
/** Pobiera tabelę z archiwalnymi kursami walut z określonej daty.
* Zwraca null w przypadku błędów, np. wtedy, gdy dla danej daty nie istnieje tabela.
*/
Tabela pobierzArchiwalneKursy(String data);
// Dzięki temu, że od Javy 8 w interfejsach można definiować metody statyczne,
// sam interfejs może słuzyć jako "fabryka obiektów".
static Pobieranie utworz(String rodzaj) {
return switch(rodzaj) {
case "xml" -> new PobieranieXML();
case "json" -> new PobieranieJSON();
default -> throw new IllegalArgumentException("Nieobsługiwany rodzaj pobierania: " + rodzaj);
};
}
}
\ No newline at end of file
package waluty;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDate;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonValue;
public class PobieranieJSON implements Pobieranie {
private static final String ADRES = "http://api.nbp.pl/api/exchangerates/tables";
public Tabela pobierzBiezaceKursy() {
return pobierzJsonZAdresu(ADRES + "/a/?format=json");
}
public Tabela pobierzArchiwalneKursy(String data) {
return pobierzJsonZAdresu(ADRES + "/a/" + data + "?format=json");
}
private Tabela pobierzJsonZAdresu(String adres) {
try {
URL url = new URL(adres);
try(InputStream input = url.openStream()) {
return wczytajStream(input);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static Tabela wczytajStream(InputStream input) {
try(JsonReader reader = Json.createReader(input)) {
// dokument zawiera [tablicę], a ta tablica zawiera {obiekt}
JsonArray array = reader.readArray();
JsonObject tabela = array.getJsonObject(0);
String typ = tabela.getString("table");
String numer = tabela.getString("no");
LocalDate data = LocalDate.parse(tabela.getString("effectiveDate"));
JsonArray waluty = tabela.getJsonArray("rates");
Tabela wynikowaTabela = new Tabela(typ, numer, data);
for(JsonValue jsonValue : waluty) {
JsonObject jsonObject = jsonValue.asJsonObject();
Waluta waluta = new Waluta(jsonObject.getString("code"),
jsonObject.getString("currency"),
jsonObject.getJsonNumber("mid").bigDecimalValue());
wynikowaTabela.dodajWalute(waluta);
}
return wynikowaTabela;
}
}
}
package waluty;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.time.LocalDate;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class PobieranieXML implements Pobieranie {
private static final String ADRES = "http://api.nbp.pl/api/exchangerates/tables";
/** Pobiera tabelę z bieżącymi kursami walut.
* Zwraca null w przypadku błędów.
*/
public Tabela pobierzBiezaceKursy() {
Document doc = wczytajXmlZAdresu(ADRES + "/a?format=xml");
return tabelaZXml(doc);
}
public Tabela pobierzArchiwalneKursy(String data) {
Document doc = wczytajXmlZAdresu(ADRES + "/A/" + data + "?format=xml");
return tabelaZXml(doc);
}
private Document wczytajXmlZAdresu(String adres) {
// Document Object Model
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
URL url = new URL(adres);
try (InputStream in = url.openStream()) {
return db.parse(in);
}
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
return null;
}
}
private Tabela tabelaZXml(Document doc) {
if (doc == null)
return null;
try {
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
// String numer = xpath.evaluate(
// "/ArrayOfExchangeRatesTable/ExchangeRatesTable/No", doc);
String nazwaTabeli = xpath.evaluate("//Table", doc);
String numerTabeli = xpath.evaluate("//No", doc);
LocalDate data = LocalDate.parse(xpath.evaluate("//EffectiveDate", doc));
Tabela tabela = new Tabela(nazwaTabeli, numerTabeli, data);
NodeList rates = (NodeList) xpath.evaluate("//Rate", doc, XPathConstants.NODESET);
final int n = rates.getLength();
for (int i = 0; i < n; i++) {
Node rate = rates.item(i);
String kod = xpath.evaluate("Code", rate);
String nazwa = xpath.evaluate("Currency", rate);
BigDecimal kurs = new BigDecimal(xpath.evaluate("Mid", rate));
Waluta waluta = new Waluta(kod, nazwa, kurs);
tabela.dodajWalute(waluta);
}
return tabela;
} catch (XPathExpressionException e) {
e.printStackTrace();
return null;
}
}
}
package waluty;
import java.math.BigDecimal;
import java.util.Scanner;
public class PrzelicznikWalutKonsola_v1 {
public static void main(String[] args) {
PobieranieXML pobieranie = new PobieranieXML();
System.out.println("Pobieram aktualne kursy...");
Tabela tabela = pobieranie.pobierzBiezaceKursy();
System.out.println(tabela);
Scanner sc = new Scanner(System.in);
while(true) {
System.out.print("\nPodaj kod waluty: ");
String kod = sc.nextLine().trim().toUpperCase();
if(kod == null || kod.isEmpty())
break;
Waluta waluta = tabela.wyszukaj(kod);
if(waluta == null) {
System.out.println("Nie ma takiej waluty.");
continue;
}
System.out.println("Wybrana waluta: " + waluta.getNazwa());
System.out.println("Aktualny kurs " + waluta.getKurs());
System.out.println();
System.out.print("Podaj kwotę: ");
if(!sc.hasNextBigDecimal()) {
System.out.println("Nieprawidłowa kwota.");
continue;
}
BigDecimal kwota = sc.nextBigDecimal();
sc.nextLine();
System.out.println(kwota + " " + kod + " = "
+ waluta.przeliczNaZlote(kwota) + " PLN");
System.out.println(kwota + " PLN " + " = "
+ waluta.przeliczNaWalute(kwota) + " " + kod);
}
}
}
package waluty;
import java.math.BigDecimal;
import java.util.Scanner;
import org.apache.commons.lang3.StringUtils;
public class PrzelicznikWalutKonsola_v2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Wybierz format komunikacji: xml | json");
String rodzaj = sc.nextLine();
Pobieranie pobieranie = Pobieranie.utworz(rodzaj);
System.out.println("Podaj datę w formacie YYYY-MM-DD lub naciśnij enter, aby pobrać najświeższe kursy.");
String data = sc.nextLine();
Tabela tabela;
if(StringUtils.isBlank(data)) {
System.out.println("Pobieram aktualne kursy...");
tabela = pobieranie.pobierzBiezaceKursy();
} else {
System.out.println("Pobieram kursy archiwalne...");
tabela = pobieranie.pobierzArchiwalneKursy(data);
}
System.out.println(tabela);
while(true) {
System.out.print("\nPodaj kod waluty: ");
String kod = sc.nextLine().trim().toUpperCase();
if(kod == null || kod.isEmpty())
break;
Waluta waluta = tabela.wyszukaj(kod);
if(waluta == null) {
System.out.println("Nie ma takiej waluty.");
continue;
}
System.out.println("Wybrana waluta: " + waluta.getNazwa());
System.out.println("Aktualny kurs " + waluta.getKurs());
System.out.println();
System.out.print("Podaj kwotę: ");
if(!sc.hasNextBigDecimal()) {
System.out.println("Nieprawidłowa kwota.");
continue;
}
BigDecimal kwota = sc.nextBigDecimal();
sc.nextLine();
System.out.println(kwota + " " + kod + " = "
+ waluta.przeliczNaZlote(kwota) + " PLN");
System.out.println(kwota + " PLN " + " = "
+ waluta.przeliczNaWalute(kwota) + " " + kod);
}
}
}
package waluty;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class Tabela {
private final String typ;
private final String numer;
private final LocalDate data;
private final List<Waluta> waluty = new ArrayList<>();
public Tabela(String typ, String numer, LocalDate data) {
this.typ = typ;
this.numer = numer;
this.data = data;
}
public String getTyp() {
return typ;
}
public String getNumer() {
return numer;
}
public LocalDate getData() {
return data;
}
public Collection<Waluta> getWaluty() {
return Collections.unmodifiableList(waluty);
}
@Override
public String toString() {
return "Tabela nr " + numer + " z dnia " + data + ", " + waluty.size() + " walut";
}
public void dodajWalute(Waluta waluta) {
this.waluty.add(waluta);
}
public Waluta wyszukaj(String kod) {
for(Waluta waluta : waluty) {
if(waluta.getKod().equals(kod)) {
return waluta;
}
}
return null;
}
public String[] getKodyWalut() {
return this.waluty.stream()
.map(Waluta::getKod)
.sorted()
.toArray(String[]::new);
}
}
package waluty;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Waluta {
private final String kod;
private final String nazwa;
private final BigDecimal kurs;
public Waluta(String kod, String nazwa, BigDecimal kurs) {
this.kod = kod;
this.nazwa = nazwa;
this.kurs = kurs;
}
public Waluta(String kod, String nazwa, String kurs) {
this(kod, nazwa, new BigDecimal(kurs));
}
public String getKod() {
return kod;
}
public String getNazwa() {
return nazwa;
}
public BigDecimal getKurs() {
return kurs;
}
@Override
public String toString() {
return "Waluta [kod=" + kod + ", nazwa=" + nazwa + ", kurs=" + kurs + "]";
}
public BigDecimal przeliczNaZlote(BigDecimal kwota) {
return kwota.multiply(kurs).setScale(2, RoundingMode.HALF_EVEN);
}
public BigDecimal przeliczNaWalute(BigDecimal kwota) {
return kwota.divide(kurs, 2, RoundingMode.HALF_EVEN);
}
}
package waluty;
import java.time.LocalDate;
import javax.swing.JOptionPane;
public class WyswietlArchiwalneKursyXML {
public static void main(String[] args) {
PobieranieXML pobieranie = new PobieranieXML();
String data = JOptionPane.showInputDialog(null, "Podaj datę w formacie YYYY-MM-DD", LocalDate.now().toString());
Tabela tabela = pobieranie.pobierzArchiwalneKursy(data);
if(tabela == null) {
System.out.println("Nie udało się pobrać. Niewłaściwa data albo problem z siecią.");
} else {
System.out.println("Pobrana tabela: " + tabela);
for (Waluta waluta : tabela.getWaluty()) {
System.out.println( " * " + waluta);
}
}
}
}
package waluty;
public class WyswietlBiezaceKursyJSON {
public static void main(String[] args) {
PobieranieJSON pobieranie = new PobieranieJSON();
Tabela tabela = pobieranie.pobierzBiezaceKursy();
System.out.println("Pobrana tabela: " + tabela);
for (Waluta waluta : tabela.getWaluty()) {
System.out.println( " * " + waluta);
}
}
}
package waluty;
public class WyswietlWszystkieKursy_XML {
public static void main(String[] args) {
System.out.println("Startujemy...");
PobieranieXML pobieranie = new PobieranieXML();
Tabela tabela = pobieranie.pobierzBiezaceKursy();
System.out.println("Mam tabelę: " + tabela);
for(Waluta waluta : tabela.getWaluty()) {
System.out.println(waluta);
}
}
}
package waluty;
import static org.junit.jupiter.api.Assertions.*;
import java.math.BigDecimal;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class WalutaTest {
private Waluta dolar;
@BeforeEach
void setUp() throws Exception {
dolar = new Waluta("USD", "dolar", "4.0000");
}
@Test
void testPrzeliczNaZlote() {
BigDecimal kwota = BigDecimal.valueOf(1000);
BigDecimal oczekiwanyWynik = new BigDecimal("4000.00");
BigDecimal wynik = dolar.przeliczNaZlote(kwota);
assertEquals(oczekiwanyWynik, wynik);
}
@Test
void testPrzeliczNaZlote_Zaokraglanie() {
Waluta innaWaluta = new Waluta("ABC", "przykładowa waluta", new BigDecimal("2.2222"));
BigDecimal kwota = new BigDecimal("3.00");
BigDecimal oczekiwanyWynik = new BigDecimal("6.67");
BigDecimal wynik = innaWaluta.przeliczNaZlote(kwota);
assertEquals(oczekiwanyWynik, wynik);
}
@Test
void testPrzeliczNaWalute() {
BigDecimal kwota = new BigDecimal("400.00");
BigDecimal oczekiwanyWynik = new BigDecimal("100.00");
BigDecimal wynik = dolar.przeliczNaWalute(kwota);
assertEquals(oczekiwanyWynik, wynik);
}
@Test
void testPrzeliczNaWalute_Zaokraglanie() {
Waluta innaWaluta = new Waluta("ABC", "przykładowa waluta", new BigDecimal("3.0000"));
BigDecimal kwota = new BigDecimal("200.00");
BigDecimal oczekiwanyWynik = new BigDecimal("66.67");
BigDecimal wynik = innaWaluta.przeliczNaWalute(kwota);
assertEquals(oczekiwanyWynik, wynik);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment