gitweb on Svarog
projekti pod git sistemom za održavanje verzija -- projects under the git version control system
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 526ca1f)
raw | patch | inline | side by side (parent: 526ca1f)
author | Ivan Pribela <ivanpribela@gmail.com> | |
Sat, 26 Dec 2015 16:15:55 +0000 (17:15 +0100) | ||
committer | Doni Pracner <quinnuendo@gmail.com> | |
Sat, 26 Dec 2015 16:15:55 +0000 (17:15 +0100) |
Stabla/konkretnoStablo/MinimalnoStablo.java | [new file with mode: 0644] | patch | blob |
Stabla/konkretnoStablo/MojeStablo.java | [new file with mode: 0644] | patch | blob |
Stabla/konkretnoStablo/Osoba.java | [new file with mode: 0644] | patch | blob |
Stabla/konkretnoStablo/Osobe.txt | [new file with mode: 0644] | patch | blob |
Stabla/konkretnoStablo/README.txt | [new file with mode: 0644] | patch | blob |
Stabla/konkretnoStablo/StabloOsobaProgram.java | [new file with mode: 0644] | patch | blob |
Stabla/konkretnoStablo/TreeIO.java | [new file with mode: 0644] | patch | blob |
Stabla/konkretnoStablo/Zadatak.txt | [new file with mode: 0644] | patch | blob |
diff --git a/Stabla/konkretnoStablo/MinimalnoStablo.java b/Stabla/konkretnoStablo/MinimalnoStablo.java
--- /dev/null
@@ -0,0 +1,27 @@
+// Konkretno stablo koje sadrzi Osobe\r
+class StabloO {\r
+ private static class Cvor {\r
+ Osoba osoba;\r
+ Cvor levo;\r
+ Cvor desno;\r
+ }\r
+ \r
+ private Cvor koren;\r
+}\r
+\r
+// Glavna klasa\r
+public class MinimalnoStablo {\r
+\r
+ // Glavni program\r
+ public static void main(String[] args) {\r
+\r
+ // Napravimo pomocni objekat za ucitavanje i ispisivanje\r
+ TreeIO<StabloO> io = new TreeIO<>(StabloO.class);\r
+\r
+ // Procitamo stablo iz fajla\r
+ StabloO stablo = io.read(Svetovid.in("Osobe.txt"));\r
+\r
+ // Ispisemo ucitano stablo\r
+ io.print(Svetovid.out, stablo);\r
+ }\r
+}\r
diff --git a/Stabla/konkretnoStablo/MojeStablo.java b/Stabla/konkretnoStablo/MojeStablo.java
--- /dev/null
@@ -0,0 +1,33 @@
+// Konkretno stablo koje sadrzi Osobe\r
+// Moze imati proizvoljno ime, ali ga treba promeniti u glavnom programu\r
+// na adekatnim mestima\r
+class BiloSta {\r
+ // treba definisati staticku podklasu koja predstavlja cvor\r
+ \r
+ // cvor treba da ima pokazivace na levo i desno podstablo\r
+ // da bi se razlikovalo koji je koji, TreeIO ocekuje da\r
+ // levo pocinje sa slovom "l", dok desno pocinje sa slovom\r
+ // "d" ili "r".\r
+ \r
+ // klasa stablo treba da ima pokazivac na koren definisanog tipa cvor\r
+\r
+ //ako klasa nije definisana kako TreeIO ocekuje, bunice se na pokretanju\r
+ \r
+}\r
+\r
+// Glavna klasa\r
+public class MojeStablo {\r
+\r
+ // Glavni program\r
+ public static void main(String[] args) {\r
+\r
+ // Napravimo pomocni objekat za ucitavanje i ispisivanje\r
+ TreeIO<BiloSta> io = new TreeIO<>(BiloSta.class);\r
+\r
+ // Procitamo stablo iz fajla\r
+ BiloSta stablo = io.read(Svetovid.in("Osobe.txt"));\r
+\r
+ // Ispisemo ucitano stablo\r
+ io.print(Svetovid.out, stablo);\r
+ }\r
+}\r
diff --git a/Stabla/konkretnoStablo/Osoba.java b/Stabla/konkretnoStablo/Osoba.java
--- /dev/null
@@ -0,0 +1,77 @@
+\r
+import java.util.Objects;\r
+\r
+// Tip podataka koji predstavlja jednu osobu\r
+public class Osoba {\r
+\r
+ private final String ime;\r
+ private final String prezime;\r
+ private final int plata;\r
+\r
+ public Osoba(String ime, String prezime, int plata) {\r
+ if (ime == null) {\r
+ throw new IllegalArgumentException("ime");\r
+ }\r
+ this.ime = ime;\r
+ if (prezime == null) {\r
+ throw new IllegalArgumentException("prezime");\r
+ }\r
+ this.prezime = prezime;\r
+ this.plata = plata;\r
+ }\r
+\r
+ public String getIme() {\r
+ return ime;\r
+ }\r
+\r
+ public String getPrezime() {\r
+ return prezime;\r
+ }\r
+\r
+ public int getPlata() {\r
+ return plata;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ final int prostBroj = 31;\r
+ int rezultat = 1;\r
+ rezultat = prostBroj * rezultat + ime.hashCode();\r
+ rezultat = prostBroj * rezultat + prezime.hashCode();\r
+ return rezultat;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+ if (obj == null) {\r
+ return false;\r
+ }\r
+ if (getClass() != obj.getClass()) {\r
+ return false;\r
+ }\r
+ Osoba that = (Osoba) obj;\r
+ if (!Objects.equals(this.ime, that.ime)) {\r
+ return false;\r
+ }\r
+ if (!Objects.equals(this.prezime, that.prezime)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return ime + " " + prezime + " " + plata;\r
+ }\r
+\r
+ public static Osoba parseOsoba(String string) {\r
+ if (string == null) {\r
+ return null;\r
+ }\r
+ String[] delovi = string.split(" ");\r
+ return new Osoba(delovi[0], delovi[1], Integer.parseInt(delovi[2]));\r
+ }\r
+}\r
diff --git a/Stabla/konkretnoStablo/Osobe.txt b/Stabla/konkretnoStablo/Osobe.txt
--- /dev/null
@@ -0,0 +1,99 @@
+ /-----(o) Pera Peric 21953\r
+ |\r
+ /-----(o) Paja Pajic 31962\r
+ | |\r
+ | | /-----(o) Mitar Mitrovic 21958\r
+ | | | |\r
+ | | | \-----(o) Dara Darinkov 31968\r
+ | | |\r
+ | | /-----(o) Mile Milic 21962\r
+ | | | |\r
+ | | | | /-----(o) Stefan Stefan-Stefan 21948\r
+ | | | | |\r
+ | | | \-----(o) Nemanja Nemanjic 41979\r
+ | | |\r
+ | \-----(o) Svetozar Svetozarevic 21954\r
+ | |\r
+ | \-----(o) Zlaja Zlajic 31981\r
+ |\r
+ /-----(o) Vuk Wolfeschlegelsteinhausenberger 41966\r
+ | |\r
+ | | /-----(o) Nina Ninkov 21971\r
+ | | |\r
+ | \-----(o) Raja Rajkovic 31985\r
+ | |\r
+ | | /-----(o) Djoka Djokic 31979\r
+ | | |\r
+ | \-----(o) Srbislava Srbislavac 41969\r
+ | |\r
+ | \-----(o) Nikolina Nikolic 31944\r
+ | |\r
+ | \-----(o) Zvonko Zvonkov 31983\r
+ |\r
+-(o) Petar Petrovic 51945\r
+ |\r
+ | /-----(o) Marko Markovic 31923\r
+ | | |\r
+ | | | /-----(o) Jakov Karajakov 21966\r
+ | | | | |\r
+ | | | | | /-----(o) Janko Jankovic 21959\r
+ | | | | | |\r
+ | | | | \-----(o) Tuta Tutevski 21974\r
+ | | | | |\r
+ | | | | \-----(o) Zorana Zoranovic-Zoranski 21955\r
+ | | | |\r
+ | | \-----(o) Zdravko Dren 61823\r
+ | | |\r
+ | | \-----(o) Filip Filipovic 21957\r
+ | |\r
+ \-----(o) Maja Majic 41972\r
+ |\r
+ | /-----(o) Mislav Mislavski 21960\r
+ | |\r
+ | /-----(o) Ljubisava Ljubisavljevic 21959\r
+ | | |\r
+ | | | /-----(o) Pera Peric 21973\r
+ | | | |\r
+ | | | /-----(o) Joksim Joksimovic 21959\r
+ | | | | |\r
+ | | | | \-----(o) Mika Mikic 31970\r
+ | | | | |\r
+ | | | | \-----(o) Baja Bajic 21967\r
+ | | | |\r
+ | | \-----(o) Zrinko Zrinkovic 31965\r
+ | | |\r
+ | | \-----(o) Hadzija Hadzi-Hadzic 21963\r
+ | | |\r
+ | | \-----(o) Jova Jovic 11943\r
+ | | |\r
+ | | \-----(o) Tatjana Tatjanic 11972\r
+ | | |\r
+ | | \-----(o) Leposava Leposavljevic 21981\r
+ | | |\r
+ | | | /-----(o) Zora Zoric 11969\r
+ | | | |\r
+ | | \-----(o) Milos Milosevic 11953\r
+ | | |\r
+ | | \-----(o) Jovan Jovanovic 11975\r
+ | |\r
+ | /-----(o) Ivana Ivanovic 31977\r
+ | |\r
+ \-----(o) Marinko Marinkovic 41965\r
+ |\r
+ \-----(o) Marina Marinovic 31984\r
+ |\r
+ \-----(o) Gojko Gajkovic 31967\r
+ |\r
+ | /-----(o) Milan McMilan 21966\r
+ | | |\r
+ | | | /-----(o) Milena Mileski 21977\r
+ | | | |\r
+ | | | /-----(o) Miladinka Miladinovic 21964\r
+ | | | |\r
+ | | \-----(o) Nikola Nikolic-Nikolic 21981\r
+ | | |\r
+ | | \-----(o) Danijela Danijelac 21979\r
+ | |\r
+ | /-----(o) Strahinja Strahimirovic 21976\r
+ | |\r
+ \-----(o) Lazar Lazarevic 21976\r
diff --git a/Stabla/konkretnoStablo/README.txt b/Stabla/konkretnoStablo/README.txt
--- /dev/null
@@ -0,0 +1,23 @@
+Primeri binarnih stabala sa konkretnim podacima klase Osoba.
+
+- Osoba.java - klasa koja predstavlja osobu: dati su ime,
+prezime i plata. Instance ove klase se cuvaju u binarnim
+stablima.
+
+- StabloOsobaProgram.java - program koji demonstrira neke
+operacije nad konkretnim stablo osoba
+
+- MinimalnoStablo.java - osnova koja definise samo potrebne
+klase i u koju se mogu dodavati novi metodi po potrebi
+
+- MojeStablo.java - primer koji pokazuje kako se mogu
+samostalno definisati klase koje predstavljaju stablo.
+
+- TreeIO.java - pomocna klasa za rad sa stablima, nije
+neophodno znati kako ona radi. Kod za ucitavanje stabla
+iz fajla kakav je dat je dat u glavnim programima, kao i
+kod za stampanje celog stabla na ekran.
+
+- Osobe.txt - fajl koji predstavlja stablo osoba.
+
+- Zadatak.txt - dodatni zadaci za samostalnu vezbu.
\ No newline at end of file
diff --git a/Stabla/konkretnoStablo/StabloOsobaProgram.java b/Stabla/konkretnoStablo/StabloOsobaProgram.java
--- /dev/null
@@ -0,0 +1,271 @@
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.NoSuchElementException;\r
+import java.util.Objects;\r
+\r
+import org.svetovid.Svetovid;\r
+\r
+// Konkretno stablo koje sadrzi ocene\r
+class StabloOsoba {\r
+\r
+ // Tip koji opisuje jedan cvor u stablu\r
+ protected static class Cvor {\r
+\r
+ // Sadrzaj cvora\r
+ public final Osoba osoba;\r
+\r
+ // Levo i desno podstablo\r
+ public final Cvor levo;\r
+ public final Cvor desno;\r
+\r
+ // Jedini konstruktor\r
+ public Cvor(Osoba osoba, Cvor levo, Cvor desno) {\r
+ this.osoba = osoba;\r
+ this.levo = levo;\r
+ this.desno = desno;\r
+ }\r
+ }\r
+\r
+ // Stablo ima referencu na korenski cvor\r
+ protected final Cvor koren;\r
+\r
+ // Kreiramo prazno stablo\r
+ public StabloOsoba() {\r
+ koren = null;\r
+ }\r
+\r
+ // Kreiramo stablo sa jednom osobom u korenu\r
+ // i praznim evim i desnim podstablom\r
+ public StabloOsoba(Osoba osoba) {\r
+ koren = new Cvor(osoba, null, null);\r
+ }\r
+\r
+ // Specijalan konstruktor koji koriste neki metodi ove klase\r
+ protected StabloOsoba(Cvor koren) {\r
+ this.koren = koren;\r
+ }\r
+\r
+ // Vraca osobu koja je direktor cele firme\r
+ public Osoba getDirektor() {\r
+ if (koren == null) { // Stablo je prazno\r
+ throw new NoSuchElementException();\r
+ }\r
+ return koren.osoba;\r
+ }\r
+\r
+ // Vraca ukupan broj osoba u stablu\r
+ public int brojOsoba() {\r
+ return brojOsoba(koren);\r
+ }\r
+\r
+ protected static int brojOsoba(Cvor cvor) {\r
+ if (cvor == null) {\r
+ return 0;\r
+ }\r
+ int broj = 1;\r
+ broj = broj + brojOsoba(cvor.levo);\r
+ broj = broj + brojOsoba(cvor.desno);\r
+ return broj;\r
+ }\r
+\r
+ // Stampa sve osobe\r
+ public void stampajSveOsobe() {\r
+ stampajSveOsobe(koren);\r
+ }\r
+\r
+ protected static void stampajSveOsobe(Cvor cvor) {\r
+ if (cvor == null) {\r
+ return;\r
+ }\r
+ stampajSveOsobe(cvor.levo);\r
+ Svetovid.out.println(cvor.osoba);\r
+ stampajSveOsobe(cvor.desno);\r
+ }\r
+\r
+ // Vraca listu svih osoba\r
+ public List<Osoba> sveOsobe() {\r
+ List<Osoba> osobe = new ArrayList<>();\r
+ sveOsobe(koren, osobe);\r
+ return osobe;\r
+ }\r
+\r
+ protected static void sveOsobe(Cvor cvor, List<Osoba> lista) {\r
+ if (cvor == null) {\r
+ return;\r
+ }\r
+ sveOsobe(cvor.levo, lista);\r
+ lista.add(cvor.osoba);\r
+ sveOsobe(cvor.desno, lista);\r
+ }\r
+\r
+ // Pronalazi datu osobu i vraca stablo sa korenom u njoj\r
+ public StabloOsoba pronadji(Osoba osoba) {\r
+ Cvor cvor = pronadji(koren, osoba);\r
+ if (cvor == null) {\r
+ return null;\r
+ }\r
+ return new StabloOsoba(cvor);\r
+ }\r
+\r
+ protected static Cvor pronadji(Cvor cvor, Osoba osoba) {\r
+ if (cvor == null) {\r
+ return null;\r
+ }\r
+ if (Objects.equals(cvor.osoba, osoba)) {\r
+ return cvor;\r
+ }\r
+ Cvor nadjenLevo = pronadji(cvor.levo, osoba);\r
+ if (nadjenLevo != null) {\r
+ return nadjenLevo;\r
+ }\r
+ Cvor nadjenDesno = pronadji(cvor.desno, osoba);\r
+ if (nadjenDesno != null) {\r
+ return nadjenDesno;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ // Pronalazi sefa date osobe\r
+ public Osoba sefOd(Osoba podredjeni) {\r
+ Cvor cvor = sefOd(koren, null, podredjeni);\r
+ if (cvor == null) {\r
+ return null;\r
+ }\r
+ return cvor.osoba;\r
+ }\r
+ \r
+ protected static Cvor sefOd(Cvor tekuci, Cvor roditelj, Osoba podredjeni) {\r
+ if (tekuci == null) {\r
+ return null;\r
+ }\r
+ if (Objects.equals(tekuci.osoba, podredjeni)) {\r
+ return roditelj;\r
+ }\r
+ Cvor roditeljLevo = sefOd(tekuci.levo, tekuci, podredjeni);\r
+ if (roditeljLevo != null) {\r
+ return roditeljLevo;\r
+ }\r
+ Cvor roditeljDesno = sefOd(tekuci.desno, tekuci, podredjeni);\r
+ if (roditeljDesno != null) {\r
+ return roditeljDesno;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ // Vraca listu svih osoba sa platom manjom od granice\r
+ public List<Osoba> sviSaPlatomIspod(int granica) {\r
+ List<Osoba> osobe = new ArrayList<>();\r
+ sviSaPlatomIspod(koren, osobe, granica);\r
+ return osobe;\r
+ }\r
+\r
+ protected static void sviSaPlatomIspod(Cvor cvor, List<Osoba> lista, int granica) {\r
+ if (cvor == null) {\r
+ return;\r
+ }\r
+ if (cvor.osoba.getPlata() < granica) {\r
+ lista.add(cvor.osoba);\r
+ }\r
+ sviSaPlatomIspod(cvor.levo, lista, granica);\r
+ sviSaPlatomIspod(cvor.desno, lista, granica);\r
+ }\r
+\r
+ // Vraca listu svih osoba podredjenih datoj\r
+ public List<Osoba> sviPodredjeni(Osoba sef) {\r
+ List<Osoba> osobe = new ArrayList<>();\r
+ Cvor cvor = pronadji(koren, sef);\r
+ if (cvor != null) {\r
+ sveOsobe(cvor, osobe);\r
+ }\r
+ return osobe;\r
+ }\r
+\r
+ // Ispisuje sve puteve u stablu od korena do svih listova\r
+ public void odDirektoraDoSpremacice() {\r
+ List<Osoba> put = new ArrayList<>();\r
+ odDirektoraDoSpremacice(koren, put);\r
+ }\r
+\r
+ protected static void odDirektoraDoSpremacice(Cvor cvor, List<Osoba> put) {\r
+ if (cvor == null) {\r
+ return;\r
+ }\r
+ put.add(cvor.osoba);\r
+ if ((cvor.levo == null) && (cvor.desno == null)) {\r
+ Svetovid.out.println(put);\r
+ }\r
+ odDirektoraDoSpremacice(cvor.levo, put);\r
+ odDirektoraDoSpremacice(cvor.desno, put);\r
+ put.remove(put.size() - 1);\r
+ }\r
+}\r
+\r
+// Glavna klasa\r
+public class StabloOsobaProgram {\r
+\r
+ // Glavni program\r
+ public static void main(String[] args) {\r
+\r
+ // Napravimo pomocni objekat za ucitavanje i ispisivanje\r
+ TreeIO<StabloOsoba> io = new TreeIO<>(StabloOsoba.class);\r
+\r
+ // Procitamo stablo iz fajla\r
+ StabloOsoba stablo = io.read(Svetovid.in("Osobe.txt"));\r
+\r
+ // Ispisemo ucitano stablo\r
+ io.print(Svetovid.out, stablo);\r
+\r
+ // Osoba koju cemo traziti u stablu \r
+ Osoba osobaX = new Osoba("Nikola", "Nikolic-Nikolic", 0);\r
+\r
+ // Broj osoba\r
+ int br = stablo.brojOsoba();\r
+ Svetovid.out.println();\r
+ Svetovid.out.println("Broj osoba u firmi: " + br);\r
+\r
+ // Stampanje svih osoba\r
+ Svetovid.out.println();\r
+ Svetovid.out.println("Te osobe su: ");\r
+ stablo.stampajSveOsobe();\r
+\r
+ // Preuzimanje osoba u listu\r
+ List<Osoba> sveOsobe = stablo.sveOsobe();\r
+ Svetovid.out.println();\r
+ Svetovid.out.println("Ili kako lista: " + sveOsobe);\r
+\r
+ // Podstablo sa Nikolom kao korenom\r
+ StabloOsoba podstablo = stablo.pronadji(osobaX);\r
+ Svetovid.out.println();\r
+ Svetovid.out.println(osobaX + " i podredjeni:");\r
+ io.print(Svetovid.out, podstablo);\r
+\r
+ // Ko je Nikolin sef\r
+ Svetovid.out.println();\r
+ Osoba sef = stablo.sefOd(osobaX);\r
+ if (sef != null) {\r
+ Svetovid.out.println("Sef od " + osobaX + " je " + sef);\r
+ } else {\r
+ Svetovid.out.println(osobaX + " je direktor");\r
+ }\r
+\r
+ // Plate\r
+ int plata = podstablo.getDirektor().getPlata();\r
+ Svetovid.out.println();\r
+ Svetovid.out.println("Plata od " + podstablo.getDirektor() + " je " + plata + "din");\r
+ List<Osoba> sviSaPlatomIspod = stablo.sviSaPlatomIspod(plata);\r
+ Svetovid.out.println();\r
+ Svetovid.out.println("Svi koji imaju platu manju od " + podstablo.getDirektor() + " su: " + sviSaPlatomIspod);\r
+\r
+ // Podredjeni\r
+ List<Osoba> sviPodredjeni = stablo.sviPodredjeni(osobaX);\r
+ Svetovid.out.println();\r
+ Svetovid.out.println("Svi koji podredjeni od " + podstablo.getDirektor() + " su: " + sviPodredjeni);\r
+\r
+ // Struktura firme od diroktora do svakog zaposlenog koji nema podredjene\r
+ Svetovid.out.println();\r
+ Svetovid.out.println("Hijerarhija sefova za svakog zaposlenog koji nema svoje podredjene:");\r
+ stablo.odDirektoraDoSpremacice();\r
+\r
+ }\r
+}\r
diff --git a/Stabla/konkretnoStablo/TreeIO.java b/Stabla/konkretnoStablo/TreeIO.java
--- /dev/null
@@ -0,0 +1,653 @@
+\r
+import java.lang.reflect.Constructor;\r
+import java.lang.reflect.Field;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.lang.reflect.Method;\r
+import java.lang.reflect.Modifier;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.svetovid.io.SvetovidReader;\r
+import org.svetovid.io.SvetovidWriter;\r
+\r
+public class TreeIO<T> {\r
+\r
+ public TreeIO(Class<T> type) {\r
+ this(type, null);\r
+ }\r
+\r
+ ////////////\r
+ // Config //\r
+ ////////////\r
+\r
+ public static class Config {\r
+\r
+ public final String nullSymbol;\r
+ public final int separation;\r
+ public final int length;\r
+\r
+ public Config() {\r
+ this(null, 1, 7);\r
+ }\r
+\r
+ public Config(String nullSymbol, int separation, int length) {\r
+ this.nullSymbol = nullSymbol;\r
+ this.separation = separation;\r
+ this.length = length;\r
+ }\r
+\r
+ public Config setNullSymbol(String nullSymbol) {\r
+ return new Config(nullSymbol, separation, length);\r
+ }\r
+\r
+ public Config setSeparation(int separation) {\r
+ return new Config(nullSymbol, separation, length);\r
+ }\r
+ \r
+ public Config setLength(int length) {\r
+ return new Config(nullSymbol, separation, length);\r
+ }\r
+ }\r
+\r
+ protected Config config;\r
+\r
+ public Config getConfig() {\r
+ return config;\r
+ }\r
+\r
+ public void setConfig(Config config) {\r
+ this.config = config;\r
+ }\r
+\r
+ //////////////\r
+ // Printing //\r
+ //////////////\r
+\r
+ public void print(SvetovidWriter out, T tree) {\r
+ Object root = getRoot(tree);\r
+ StringBuilder builder = new StringBuilder();\r
+ appendTree(builder, root, config);\r
+ out.print(builder.toString());\r
+ }\r
+\r
+ protected void appendTree(StringBuilder builder, Object tree, Config config) {\r
+ String[] buildingBlocks = generateBuildingBlocks(config);\r
+ appendRight(builder, tree, config, buildingBlocks, true, buildingBlocks[5]);\r
+ appendNode(builder, tree, config, buildingBlocks[4]);\r
+ appendLeft(builder, tree, config, buildingBlocks, false, buildingBlocks[5]);\r
+ }\r
+\r
+ protected void appendNode(StringBuilder builder, Object tree, Config config, String prefix) {\r
+ builder.append(prefix);\r
+ if (tree == null) {\r
+ builder.append(config.nullSymbol == null ? VERTICAL_SYMBOL : config.nullSymbol);\r
+ } else {\r
+ builder.append("(o)");\r
+ Object element = getElement(tree);\r
+ if (element != null) {\r
+ builder.append(" ");\r
+ builder.append(element.toString());\r
+ }\r
+ }\r
+ builder.append("\n");\r
+ }\r
+\r
+ protected void appendRight(StringBuilder builder, Object tree, Config config, String[] buildingBlocks, boolean isRight, String prefix) {\r
+ if (tree == null) {\r
+ return;\r
+ }\r
+ Object subtree = getRight(tree);\r
+ if ((config.nullSymbol != null) || (subtree != null)) {\r
+ appendSubtree(builder, subtree, config, buildingBlocks, true, prefix);\r
+ for (int i = 0; i < config.separation; i++) {\r
+ appendEmpty(builder, buildingBlocks, prefix);\r
+ }\r
+ }\r
+ }\r
+\r
+ protected void appendLeft(StringBuilder builder, Object tree, Config config, String[] buildingBlocks, boolean isRight, String prefix) {\r
+ if (tree == null) {\r
+ return;\r
+ }\r
+ Object subtree = getLeft(tree);\r
+ if ((config.nullSymbol != null) || (subtree != null)) {\r
+ for (int i = 0; i < config.separation; i++) {\r
+ appendEmpty(builder, buildingBlocks, prefix);\r
+ }\r
+ appendSubtree(builder, subtree, config, buildingBlocks, false, prefix);\r
+ }\r
+ }\r
+\r
+ protected void appendEmpty(StringBuilder builder, String[] buildingBlocks, String prefix) {\r
+ builder.append(prefix);\r
+ builder.append(buildingBlocks[2]);\r
+ builder.append("\n");\r
+ }\r
+\r
+ protected void appendSubtree(StringBuilder builder, Object tree, Config config, String[] buildingBlocks, boolean isRight, String prefix) {\r
+ String myPrefix = prefix;\r
+ if (isRight == true) {\r
+ myPrefix = myPrefix + buildingBlocks[1];\r
+ }\r
+ if (isRight == false) {\r
+ myPrefix = myPrefix + buildingBlocks[3];\r
+ }\r
+ String noviPrefix = prefix + (!isRight ? buildingBlocks[2] : buildingBlocks[0]);\r
+ appendRight(builder, tree, config, buildingBlocks, isRight, noviPrefix);\r
+ appendNode(builder, tree, config, myPrefix);\r
+ noviPrefix = prefix + (isRight ? buildingBlocks[2] : buildingBlocks[0]);\r
+ appendLeft(builder, tree, config, buildingBlocks, isRight, noviPrefix);\r
+ }\r
+\r
+ protected static final String EMPTY_SYMBOL = " ";\r
+ protected static final String RIGHT_SYMBOL = "/";\r
+ protected static final String VERTICAL_SYMBOL = "|";\r
+ protected static final String LEFT_SYMBOL = "\\";\r
+ protected static final String HORIZONTAL_SYMBOL = "-";\r
+\r
+ protected String[] generateBuildingBlocks(Config config) {\r
+ String[] blocks = new String[6];\r
+ blocks[0] = generateBlock(EMPTY_SYMBOL, EMPTY_SYMBOL, EMPTY_SYMBOL, config.length - 2);\r
+ blocks[1] = generateBlock(EMPTY_SYMBOL, RIGHT_SYMBOL, HORIZONTAL_SYMBOL, config.length - 2);\r
+ blocks[2] = generateBlock(EMPTY_SYMBOL, VERTICAL_SYMBOL, EMPTY_SYMBOL, config.length - 2);\r
+ blocks[3] = generateBlock(EMPTY_SYMBOL, LEFT_SYMBOL, HORIZONTAL_SYMBOL, config.length - 2);\r
+ blocks[4] = HORIZONTAL_SYMBOL;\r
+ blocks[5] = EMPTY_SYMBOL;\r
+ return blocks;\r
+ }\r
+\r
+ protected String generateBlock(String emptySymbol, String startSymbol, String repeatSymbol, int repeatCount) {\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append(emptySymbol);\r
+ builder.append(startSymbol);\r
+ for (int i = 0; i < repeatCount; i++) {\r
+ builder.append(repeatSymbol);\r
+ }\r
+ return builder.toString();\r
+ }\r
+\r
+ /////////////\r
+ // Reading //\r
+ /////////////\r
+\r
+ public T read(SvetovidReader in) {\r
+ return newTree(parseTree(in, config)); \r
+ }\r
+\r
+ protected Object parseTree(SvetovidReader in, Config config) {\r
+ List<Object> elements = new ArrayList<>();\r
+ List<Integer> levels = new ArrayList<>();\r
+ Pattern levelPattern = Pattern.compile("[\\Q" + LEFT_SYMBOL + HORIZONTAL_SYMBOL + RIGHT_SYMBOL + "\\E]");\r
+ String line = in.readLine();\r
+ while ((line != null) && !line.isEmpty()) {\r
+ Matcher matcher = levelPattern.matcher(line);\r
+ int level = -1;\r
+ if (matcher.find()) {\r
+ level = matcher.start();\r
+ }\r
+ if (level != -1 && (config.nullSymbol == null || !line.endsWith(config.nullSymbol))) {\r
+ Object tree = parseTree(line);\r
+ elements.add(tree);\r
+ levels.add(level);\r
+ }\r
+ line = in.readLine();\r
+ }\r
+ Object tree = formTree(0, elements.size(), levels, elements);\r
+ return tree;\r
+ }\r
+\r
+ protected Object parseTree(String line) {\r
+ String value;\r
+ int beginIndex = line.indexOf('(');\r
+ int endIndex = line.indexOf(')');\r
+ if ((beginIndex != -1) && (endIndex != -1) && (beginIndex < endIndex)) {\r
+ value = line.substring(endIndex + 1);\r
+ if (value.length() == 0) {\r
+ value = null;\r
+ } else {\r
+ value = value.substring(1);\r
+ }\r
+ } else {\r
+ throw new NumberFormatException(line);\r
+ }\r
+ Object element = null;\r
+ if (value != null) {\r
+ element = newElement(value);\r
+ }\r
+ Object tree = newNode(element);\r
+ return tree;\r
+ }\r
+\r
+ protected Object formTree(int beginIndex, int endIndex, List<Integer> levels, List<Object> elements) {\r
+ if (beginIndex >= endIndex) {\r
+ return null;\r
+ }\r
+ int minIndex = beginIndex;\r
+ int minLevel = levels.get(minIndex);\r
+ for (int i = beginIndex + 1; i < endIndex; i++) {\r
+ int level = levels.get(i);\r
+ if (level < minLevel) {\r
+ minLevel = level;\r
+ minIndex = i;\r
+ }\r
+ }\r
+ Object tree = elements.get(minIndex);\r
+ Object left = formTree(minIndex + 1, endIndex, levels, elements);\r
+ Object right = formTree(beginIndex, minIndex, levels, elements);\r
+ setLeft(tree, left);\r
+ setRight(tree, right);\r
+ return tree;\r
+ }\r
+\r
+ ///////////\r
+ // Magic //\r
+ ///////////\r
+\r
+ @SuppressWarnings("unchecked")\r
+ public TreeIO(Class<T> type, Config config) {\r
+\r
+ // Tree type\r
+ if (type == null) {\r
+ throw new IllegalArgumentException("Prosledjena klasa je null");\r
+ }\r
+ this.treeType = type;\r
+ if (Modifier.isAbstract(this.treeType.getModifiers())) {\r
+ throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " ne sme da bude apstraktna");\r
+ }\r
+\r
+ // Node type\r
+ Class<?>[] declaredClasses = treeType.getDeclaredClasses();\r
+ if (declaredClasses.length == 0) {\r
+ throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema unutrasnju klasu koja predstavlja cvorove");\r
+ }\r
+ Class<?> staticOne = null;\r
+ boolean multiStatic = false;\r
+ for (Class<?> cl: declaredClasses) {\r
+ if (Modifier.isStatic(cl.getModifiers())) {\r
+ if (staticOne == null) {\r
+ staticOne = cl;\r
+ } else {\r
+ multiStatic = true;\r
+ }\r
+ }\r
+ }\r
+ if (staticOne == null) {\r
+ throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema staticku unutrasnju klasu koja predstavlja cvorove");\r
+ }\r
+ if (multiStatic) {\r
+ throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " ima vise unutrasnjih statickih klasa, a mora biti samo jedna");\r
+ }\r
+ this.nodeType = staticOne;\r
+ if (Modifier.isAbstract(this.nodeType.getModifiers())) {\r
+ throw new IllegalArgumentException("Klasa " + this.nodeType.getName() + " ne sme da bude apstraktna");\r
+ }\r
+ if (!Modifier.isStatic(this.nodeType.getModifiers())) {\r
+ throw new IllegalArgumentException("Klasa " + this.nodeType.getName() + " mora da bude staticka");\r
+ }\r
+\r
+ // Tree constructors\r
+ Constructor<?>[] declaredConstructors = this.treeType.getDeclaredConstructors();\r
+ Constructor<T> defaultTreeConstructor = null;\r
+ Constructor<T> treeConstructor = null;\r
+ for (Constructor<?> constructor : declaredConstructors) {\r
+ boolean throwingExceptions = false;\r
+ for (Class<?> exception : constructor.getExceptionTypes()) {\r
+ if (!RuntimeException.class.isAssignableFrom(exception)) {\r
+ throwingExceptions = true;\r
+ }\r
+ }\r
+ Class<?>[] parameters = constructor.getParameterTypes();\r
+ if (parameters.length == 0\r
+ && !throwingExceptions) {\r
+ defaultTreeConstructor = (Constructor<T>) constructor;\r
+ }\r
+ if (parameters.length == 1\r
+ && parameters[0].isAssignableFrom(this.nodeType)\r
+ && !throwingExceptions) {\r
+ treeConstructor = (Constructor<T>) constructor;\r
+ }\r
+ }\r
+ if (defaultTreeConstructor == null && treeConstructor == null) {\r
+ throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema "\r
+ + this.nodeType.getSimpleName() + "() ili "\r
+ + this.nodeType.getSimpleName() + "(" + this.nodeType.getName() + ") konstruktor");\r
+ }\r
+ this.defaultTreeConstructor = defaultTreeConstructor;\r
+ if (this.defaultTreeConstructor != null) {\r
+ this.defaultTreeConstructor.setAccessible(true);\r
+ }\r
+ this.treeConstructor = treeConstructor;\r
+ if (this.treeConstructor != null) {\r
+ this.treeConstructor.setAccessible(true);\r
+ }\r
+\r
+ // Tree root field\r
+ Field[] declaredFields = this.treeType.getDeclaredFields();\r
+ Field rootField = null;\r
+ for (Field field : declaredFields) {\r
+ if (Modifier.isStatic(field.getModifiers())) {\r
+ continue;\r
+ }\r
+ if (field.getType().isAssignableFrom(this.nodeType)) {\r
+ if (rootField != null) {\r
+ throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " ima vise polja koji bi mogli predstavljati koren stabla");\r
+ }\r
+ rootField = field;\r
+ }\r
+ }\r
+ if (rootField == null) {\r
+ throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema polje za predstavljanje korena");\r
+ }\r
+ this.rootField = rootField;\r
+ if (Modifier.isStatic(this.rootField.getModifiers())) {\r
+ throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.rootField.getName() + " ne sme da bude staticko");\r
+ }\r
+ this.rootField.setAccessible(true);\r
+\r
+ // Node fields\r
+ declaredFields = this.nodeType.getDeclaredFields();\r
+ if (declaredFields.length == 0) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema deklarisanih polja");\r
+ }\r
+ Field elementField = null;\r
+ Field leftField = null;\r
+ Field rightField = null;\r
+ for (Field field : declaredFields) {\r
+ if (Modifier.isStatic(field.getModifiers())) {\r
+ continue;\r
+ }\r
+ String fieldName = field.getName();\r
+ if (fieldName.startsWith("e") || fieldName.startsWith("i") || fieldName.startsWith("o")) {\r
+ if (elementField != null) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " ima vise polja za predstavljanje elementa");\r
+ }\r
+ elementField = field;\r
+ }\r
+ if (fieldName.startsWith("l")\r
+ && field.getType().isAssignableFrom(this.nodeType)) {\r
+ if (leftField != null) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " ima vise polja za predstavljanje levog podstabla");\r
+ }\r
+ leftField = field;\r
+ }\r
+ if (fieldName.startsWith("d") || fieldName.startsWith("r")\r
+ && field.getType().isAssignableFrom(this.nodeType)) {\r
+ if (rightField != null) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " ima vise polja za predstavljanje desnog podstabla");\r
+ }\r
+ rightField = field;\r
+ }\r
+ }\r
+ if (elementField == null) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema polje za predstavljanje elementa");\r
+ }\r
+ if (leftField == null) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema polje za predstavljanje levog podstabla");\r
+ }\r
+ if (rightField == null) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema polje za predstavljanje desnog podstabla");\r
+ }\r
+ this.elementField = elementField;\r
+ if (Modifier.isStatic(this.elementField.getModifiers())) {\r
+ throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.elementField.getName() + " ne sme da bude staticko");\r
+ }\r
+ this.elementField.getModifiers();\r
+ \r
+ this.elementField.setAccessible(true);\r
+ this.leftField = leftField;\r
+ if (Modifier.isStatic(this.leftField.getModifiers())) {\r
+ throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.leftField.getName() + " ne sme da bude staticko");\r
+ }\r
+ this.leftField.setAccessible(true);\r
+ this.rightField = rightField;\r
+ if (Modifier.isStatic(this.rightField.getModifiers())) {\r
+ throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.rightField.getName() + " ne sme da bude staticko");\r
+ }\r
+ this.rightField.setAccessible(true);\r
+\r
+ // Element type\r
+ this.elementType = elementField.getType();\r
+\r
+ // Node constructors\r
+ declaredConstructors = this.nodeType.getDeclaredConstructors();\r
+ Constructor<?> defaultNodeConstructor = null;\r
+ Constructor<?> nodeConstructor = null;\r
+ Constructor<?> nodeConstructor3 = null;\r
+ for (Constructor<?> constructor : declaredConstructors) {\r
+ boolean throwingExceptions = false;\r
+ for (Class<?> exception : constructor.getExceptionTypes()) {\r
+ if (!RuntimeException.class.isAssignableFrom(exception)) {\r
+ throwingExceptions = true;\r
+ }\r
+ }\r
+ Class<?>[] parameters = constructor.getParameterTypes();\r
+ if (parameters.length == 0\r
+ && !throwingExceptions) {\r
+ defaultNodeConstructor = constructor;\r
+ }\r
+ if (parameters.length == 1\r
+ && parameters[0].isAssignableFrom(this.elementType)\r
+ && !throwingExceptions) {\r
+ nodeConstructor = constructor;\r
+ }\r
+ if (parameters.length == 3\r
+ && parameters[0].isAssignableFrom(this.elementType)\r
+ && parameters[1].isAssignableFrom(this.nodeType)\r
+ && parameters[2].isAssignableFrom(this.nodeType)\r
+ && !throwingExceptions) {\r
+ nodeConstructor3 = constructor;\r
+ }\r
+ }\r
+ if (defaultNodeConstructor == null && nodeConstructor == null && nodeConstructor3 == null) {\r
+ throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema "\r
+ + this.nodeType.getSimpleName() + "() ili "\r
+ + this.nodeType.getSimpleName() + "(" + this.elementType.getName() + ") ili "\r
+ + this.nodeType.getSimpleName() + "(" + this.elementType.getName() + ", " + this.nodeType.getSimpleName() + ", " + this.nodeType.getSimpleName() + ") konstruktor");\r
+ }\r
+ this.defaultNodeConstructor = defaultNodeConstructor;\r
+ if (this.defaultNodeConstructor != null) {\r
+ this.defaultNodeConstructor.setAccessible(true);\r
+ }\r
+ this.nodeConstructor = nodeConstructor;\r
+ if (this.nodeConstructor != null) {\r
+ this.nodeConstructor.setAccessible(true);\r
+ }\r
+ this.nodeConstructor3 = nodeConstructor3;\r
+ if (this.nodeConstructor3 != null) {\r
+ this.nodeConstructor3.setAccessible(true);\r
+ }\r
+\r
+ // Element methods\r
+ Method elementFactoryMethod = null;\r
+ Method[] declaredMethods = this.elementType.getDeclaredMethods();\r
+ for (Method method : declaredMethods) {\r
+ if (!Modifier.isStatic(method.getModifiers())) {\r
+ continue;\r
+ }\r
+ boolean throwingExceptions = false;\r
+ for (Class<?> exception : method.getExceptionTypes()) {\r
+ if (!RuntimeException.class.isAssignableFrom(exception)) {\r
+ throwingExceptions = true;\r
+ }\r
+ }\r
+ String methodName = method.getName();\r
+ boolean familiarName = methodName.equals("fromString")\r
+ || methodName.equals("valueOf")\r
+ || methodName.equals("parse" + this.elementType.getSimpleName());\r
+ boolean goodParameters = method.getParameterTypes().length == 1 && (method.getParameterTypes()[0] == String.class || method.getParameterTypes()[0] == Object.class);\r
+ if (familiarName\r
+ && goodParameters\r
+ && this.elementType.isAssignableFrom(method.getReturnType())\r
+ && !throwingExceptions) {\r
+ if (elementFactoryMethod != null) {\r
+ throw new IllegalArgumentException("Klasa " + this.elementType.getName() + " ima vise "\r
+ + this.elementType.getSimpleName() + " fromString(String), "\r
+ + this.elementType.getSimpleName() + " valueOf(String) i "\r
+ + this.elementType.getSimpleName() + " parse" + this.elementType.getSimpleName() + "(String) metoda");\r
+ }\r
+ elementFactoryMethod = method;\r
+ }\r
+ }\r
+ if (elementFactoryMethod == null) {\r
+ throw new IllegalArgumentException("Klasa " + this.elementType.getName() + " nema "\r
+ + this.elementType.getSimpleName() + " fromString(String), "\r
+ + this.elementType.getSimpleName() + " valueOf(String) ili "\r
+ + this.elementType.getSimpleName() + " parse" + this.elementType.getSimpleName() + "(String) metod");\r
+ }\r
+ this.elementFactoryMethod = elementFactoryMethod;\r
+ this.elementFactoryMethod.setAccessible(true);\r
+\r
+ // Config\r
+ if (config == null) {\r
+ config = new Config();\r
+ }\r
+ this.config = config;\r
+\r
+ }\r
+\r
+ protected final Class<T> treeType;\r
+ protected final Constructor<T> treeConstructor;\r
+ protected final Constructor<T> defaultTreeConstructor;\r
+ protected final Field rootField;\r
+ protected final Class<?> nodeType;\r
+ protected final Field elementField;\r
+ protected final Field leftField;\r
+ protected final Field rightField;\r
+ protected final Constructor<?> nodeConstructor3;\r
+ protected final Constructor<?> nodeConstructor;\r
+ protected final Constructor<?> defaultNodeConstructor;\r
+ protected final Class<?> elementType;\r
+ protected final Method elementFactoryMethod;\r
+\r
+ private Object getRoot(T tree) {\r
+ try {\r
+ Object value = rootField.get(tree);\r
+ return value;\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ return null;\r
+ }\r
+ }\r
+ \r
+ private void setRoot(T tree, Object root) {\r
+ try {\r
+ rootField.set(tree, root);\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ }\r
+ }\r
+\r
+ private Object getElement(Object node) {\r
+ try {\r
+ Object value = elementField.get(node);\r
+ return value;\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ return null;\r
+ }\r
+ }\r
+ \r
+ private void setElement(Object node, Object value) {\r
+ try {\r
+ elementField.set(node, value);\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ }\r
+ }\r
+\r
+ private Object getLeft(Object node) {\r
+ try {\r
+ Object value = leftField.get(node);\r
+ return value;\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ return null;\r
+ }\r
+ }\r
+\r
+ private void setLeft(Object node, Object value) {\r
+ try {\r
+ leftField.set(node, value);\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ }\r
+ }\r
+\r
+ private Object getRight(Object node) {\r
+ try {\r
+ Object value = rightField.get(node);\r
+ return value;\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ return null;\r
+ }\r
+ }\r
+\r
+ private void setRight(Object node, Object value) {\r
+ try {\r
+ rightField.set(node, value);\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ }\r
+ }\r
+\r
+ private Object newElement(String value) {\r
+ try {\r
+ return elementFactoryMethod.invoke(null, value);\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ return null;\r
+ } catch (InvocationTargetException e) {\r
+ // Will not be a checked exception\r
+ RuntimeException cause = (RuntimeException) e.getCause();\r
+ throw cause;\r
+ }\r
+ }\r
+\r
+ private Object newNode(Object element) {\r
+ try {\r
+ if (nodeConstructor != null) {\r
+ return nodeConstructor.newInstance(element);\r
+ }\r
+ if (nodeConstructor3 != null) {\r
+ return nodeConstructor3.newInstance(element, null, null);\r
+ }\r
+ Object node = defaultNodeConstructor.newInstance();\r
+ setElement(node, element);\r
+ return node;\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ return null;\r
+ } catch (InstantiationException e) {\r
+ // Will never happen\r
+ return null;\r
+ } catch (InvocationTargetException e) {\r
+ // Will not be a checked exception\r
+ RuntimeException cause = (RuntimeException) e.getCause();\r
+ throw cause;\r
+ }\r
+ }\r
+\r
+ private T newTree(Object root) {\r
+ try {\r
+ if (treeConstructor != null) {\r
+ return treeConstructor.newInstance(root);\r
+ }\r
+ T tree = defaultTreeConstructor.newInstance();\r
+ setRoot(tree, root);\r
+ return tree;\r
+ } catch (IllegalAccessException e) {\r
+ // Will never happen\r
+ return null;\r
+ } catch (InstantiationException e) {\r
+ // Will never happen\r
+ return null;\r
+ } catch (InvocationTargetException e) {\r
+ // Will not be a checked exception\r
+ RuntimeException cause = (RuntimeException) e.getCause();\r
+ throw cause;\r
+ }\r
+ }\r
+}\r
diff --git a/Stabla/konkretnoStablo/Zadatak.txt b/Stabla/konkretnoStablo/Zadatak.txt
--- /dev/null
@@ -0,0 +1,100 @@
+Zadatak\r
+=======\r
+\r
+Data je klasa koja implementira binarno stablo osoba.\r
+Takodje, je dat i glavni program koji ucitava jedno stablo i\r
+poziva neke od operacija nad njim.\r
+\r
+Implementirati operacije navedene u nastavku i ilustrovati\r
+njihov rad pozivanjem iz glavnog programa. Svaki metod je\r
+potrebno implementirati kao javan metod klase koja\r
+predstavlja stablo, a po potrebi se definisu pomocni\r
+staticki metodi koji ce rekurzivno obilaziti stablo. Pomocni\r
+metodi ce cesto biti istog imena kao i glavni metod.\r
+\r
+Primer implementacije metoda i njihovih poziva postoji u\r
+`StabloOsobaProgram.java`.\r
+\r
+Preporucuje se da se zadati metodi dodaju u\r
+`MinimalnoStablo.java`, mada ih je moguce dodavati i u\r
+`StabloOsobaProgram.java` ili `MojeStablo.java`.\r
+\r
+\r
+Metodi\r
+======\r
+\r
+\r
+public double prosecnaPlata()\r
+-----------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+izracunava i vraca prosecnu platu svih zaposlenih.\r
+\r
+Ako je stablo prazno, prosecna plata je 0.0.\r
+\r
+\r
+public Osoba osobaSaNajvecomPlatom()\r
+------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+pronalazi i vraca osobu koja ima najvecu platu.\r
+\r
+\r
+public List<Osoba> sviPodredjeni(Osoba o)\r
+-----------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih zaposlenih koji su podredjeni\r
+datoj osobi.\r
+\r
+Lista ne ukljucuje prosledjenu osobu.\r
+\r
+Ako je stablo prazno, ili se osoba ne nalazi u\r
+stablu, vratiti praznu listu.\r
+\r
+\r
+public List<Osoba> sviNadredjeni(Osoba o)\r
+-----------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih nadredjenih datoj osobi pocevsi\r
+od generalnog direktora.\r
+\r
+\r
+public List<Osoba> sviSaIstomPlatom()\r
+-------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+pronalazi i vraca sve osobe koje imaju platu\r
+istu kao jos neka druga osoba.\r
+\r
+\r
+public void ispisiOsobeSaVecomPlatomOdSefa()\r
+--------------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+ispisuje sve osobe koje imaju vecu platu od svog sefa.\r
+\r
+\r
+public List<Osoba> vecaPlataOdDirektora()\r
+-----------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih zaposlenih koji imaju vecu\r
+platu od generalnog direktora (koren celog stabla).\r
+\r
+\r
+public List<Osoba> plataIspodProseka()\r
+--------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih zaposlenih koji imaju platu ispod\r
+proseka u firmi.\r
+\r
+\r
+public Osoba drugaPoReduSaNajvecomPlatom()\r
+------------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+pronalazi i vraca osobu koja je druga po redu\r
+po velicini plate.\r