Dokumentation

This commit is contained in:
ngb
2022-12-08 21:16:01 +01:00
parent 8de3c41b9b
commit 9fc58b05b6
6 changed files with 267 additions and 59 deletions

View File

@@ -5,7 +5,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Eine Hilfsklasse um Dinge zu zählen. * Eine Helferklasse, um Dinge zu zählen.
* <p> * <p>
* Im einfachsten Fall kann der Zähler als geteilte Zählvariable genutzt werden, * Im einfachsten Fall kann der Zähler als geteilte Zählvariable genutzt werden,
* die mit {@link #inc()} und {@link #dec()} aus verschiedenen Objekten oder * die mit {@link #inc()} und {@link #dec()} aus verschiedenen Objekten oder
@@ -13,11 +13,11 @@ import java.util.concurrent.atomic.AtomicInteger;
* <p> * <p>
* Der Zähler kann aber auch Objekte zählen, indem die Instanzen an * Der Zähler kann aber auch Objekte zählen, indem die Instanzen an
* {@link #count(Object)} übergeben werden. Am Ende kann mit {@link #getCount()} * {@link #count(Object)} übergeben werden. Am Ende kann mit {@link #getCount()}
* die Anzahl der Objkete abgerufen werden. * die Anzahl der Objekte abgerufen werden.
* <p> * <p>
* Handelt es sich bei den Objekten um Zahlen, dann merkt sich ein Zähler auch * Handelt es sich bei den Objekten um Zahlen, dann merkt sich ein
* das Maximum, das Minimum, die Summe und den Durchschnitt der gezählten * {@code Counter} auch das Maximum, das Minimum, die Summe und den Durchschnitt
* Werte. * der gezählten Werte.
* <p> * <p>
* Ein Zähler kann auch komplette Arrays oder Listen von Zahlen zählen und die * Ein Zähler kann auch komplette Arrays oder Listen von Zahlen zählen und die
* obigen Statistiken auswerten. * obigen Statistiken auswerten.
@@ -96,31 +96,42 @@ public final class Counter {
} }
/** /**
* Gibt die aktuelle Anzahl zurück.
* @return Die aktuelle Anzahl. * @return Die aktuelle Anzahl.
*/ */
public int getCount() { public int getCount() {
return count.get(); return count.get();
} }
/**
* @return Das Maxium der bisher gezählten Werte.
*/
public double getMax() { public double getMax() {
synchronized( count ) { synchronized( count ) {
return max; return max;
} }
} }
/**
* @return Das Minimum der bisher gezählten Werte.
*/
public double getMin() { public double getMin() {
synchronized( count ) { synchronized( count ) {
return min; return min;
} }
} }
/**
* @return Die Summe der bisher gezählten Werte.
*/
public double getSum() { public double getSum() {
synchronized( count ) { synchronized( count ) {
return sum; return sum;
} }
} }
/**
* @return Der Mittelwert der bisher gezählten Werte.
*/
public double getAvg() { public double getAvg() {
if( Double.isNaN(sum) ) { if( Double.isNaN(sum) ) {
return Double.NaN; return Double.NaN;
@@ -129,13 +140,27 @@ public final class Counter {
} }
} }
/**
* Setzt den Zähler auf den angegebenen Wert.
* <p>
* Die anderen Statistiken werden nicht verändert.
*
* @param count Der neue Wert des Zählers.
* @return Dieser Zähler selbst (method chaining).
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public Counter setCount( int count ) { public Counter setCount( int count ) {
this.count.set(count); this.count.set(count);
return this; return this;
} }
/**
* Setzt den Zähler auf Null.
* <p>
* Die Statistiken werden auf {@link Double#NaN} gesetzt.
*
* @return Dieser Zähler selbst (method chaining).
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public Counter reset() { public Counter reset() {
count.set(0); count.set(0);
@@ -147,18 +172,40 @@ public final class Counter {
return this; return this;
} }
/**
* Erhöht den Zähler um Eins.
* <p>
* Die anderen Statistiken werden nicht verändert.
*
* @return Dieser Zähler selbst (method chaining).
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public Counter inc() { public Counter inc() {
this.count.incrementAndGet(); this.count.incrementAndGet();
return this; return this;
} }
/**
* Verringert den Zähler um Eins.
* <p>
* Die anderen Statistiken werden nicht verändert.
*
* @return Dieser Zähler selbst (method chaining).
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public Counter dec() { public Counter dec() {
this.count.decrementAndGet(); this.count.decrementAndGet();
return this; return this;
} }
/**
* Zählt den angegebenen Wert.
* <p>
* Erhöht den Zähler um Eins und aktualisiert die Statistiken.
*
* @param value Der neue Wert.
* @return Dieser Zähler selbst (method chaining).
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public Counter count( double value ) { public Counter count( double value ) {
inc(); inc();
@@ -173,11 +220,27 @@ public final class Counter {
return this; return this;
} }
/**
* Zählt die angegebene Zahl.
* <p>
* Erhöht den Zähler um Eins und aktualisiert die Statistiken.
*
* @param num Die neue Zahl.
* @return Dieser Zähler selbst (method chaining).
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public Counter count( Number num ) { public Counter count( Number num ) {
return count(num.doubleValue()); return count(num.doubleValue());
} }
/**
* Zählt das angegebenen Objekt.
* <p>
* Erhöht den Zähler um Eins.
*
* @param obj Ein beliebiges Objekt.
* @return Dieser Zähler selbst (method chaining).
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public Counter count( Object obj ) { public Counter count( Object obj ) {
if( obj instanceof Number ) { if( obj instanceof Number ) {
@@ -188,6 +251,13 @@ public final class Counter {
} }
} }
/**
* Zöhlt alle Werte im angegebenen Array.
*
* @param values Das Array der neuen Werte.
* @return Dieser Zähler selbst (method chaining).
* @see #count(double)
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public synchronized Counter countAll( double[] values ) { public synchronized Counter countAll( double[] values ) {
for( double value : values ) { for( double value : values ) {
@@ -196,6 +266,13 @@ public final class Counter {
return this; return this;
} }
/**
* Zöhlt alle Werte im angegebenen Array.
*
* @param values Das Array der neuen Werte.
* @return Dieser Zähler selbst (method chaining).
* @see #count(double)
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public synchronized Counter countAll( int[] values ) { public synchronized Counter countAll( int[] values ) {
for( double value : values ) { for( double value : values ) {
@@ -204,6 +281,13 @@ public final class Counter {
return this; return this;
} }
/**
* Zöhlt alle Zahlen im angegebenen Array.
*
* @param values Das Array der neuen Zahlen.
* @return Dieser Zähler selbst (method chaining).
* @see #count(Number)
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public synchronized Counter countAll( Number[] values ) { public synchronized Counter countAll( Number[] values ) {
for( Number value : values ) { for( Number value : values ) {
@@ -212,6 +296,13 @@ public final class Counter {
return this; return this;
} }
/**
* Zöhlt alle Zahlen in der angegebenen Sammlung.
*
* @param values Die Sammlung der neuen Zahlen.
* @return Dieser Zähler selbst (method chaining).
* @see #count(Number)
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public synchronized Counter countAll( Collection<Number> values ) { public synchronized Counter countAll( Collection<Number> values ) {
for( Number value : values ) { for( Number value : values ) {

View File

@@ -3,7 +3,7 @@ package schule.ngb.zm.util;
import java.util.Random; import java.util.Random;
/** /**
* Zufallsgenerator für Perlin-Noise. * Generator für Perlin-Noise.
* <p> * <p>
* Die Implementierung basiert auf dem von Ken Perlin entwickelten Algorithmus * Die Implementierung basiert auf dem von Ken Perlin entwickelten Algorithmus
* und wurde anhand der <a * und wurde anhand der <a
@@ -18,7 +18,7 @@ public class Noise {
private static final int M = N - 1; private static final int M = N - 1;
/** /**
* Interne Permutationstabelle für diesen Generator * Interne Permutationstabelle für diesen Generator.
*/ */
private int[] p; private int[] p;

View File

@@ -3,13 +3,13 @@ package schule.ngb.zm.util;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Eine Hilfsklasse zur Zeitmessung im Nanosekundenbereich. * Helferklasse zur Zeitmessung im Nanosekundenbereich.
* <p> * <p>
* Die Klasse kann zum Beispiel genutzt werden, um die Laufzeit eines * Mit einem {@code Timer} kann zum Beispiel die Laufzeit eines Algorithmus
* Quelltextes zu messen. Wie eine echte Stoppuhr läuft der {@code Timer} * gemessen werden. Wie eine echte Stoppuhr läuft der {@code Timer} weiter, wenn
* weiter, wenn nach einem {@link #stop()} wieder {@link #start()} aufgerufen * nach einem {@link #stop()} wieder {@link #start()} aufgerufen wird. Soll die
* wird. Soll die Zeitmessung wieder bei null beginnen, muss vorher * Zeitmessung wieder bei null beginnen, muss vorher {@link #reset()} genutzt
* {@link #reset()} genutzt werden. * werden.
* <p> * <p>
* Die gemessene Zeit kann in {@link #getMillis() Millisekunden} oder * Die gemessene Zeit kann in {@link #getMillis() Millisekunden} oder
* {@link #getSeconds() Sekunden} abgerufen werden. Wird eine noch größere * {@link #getSeconds() Sekunden} abgerufen werden. Wird eine noch größere
@@ -100,7 +100,7 @@ public final class Timer {
} }
/** /**
* Stoppt den {@code Timer}, wenn er derzeit läuft. Die gemessene Zeit wird * Stoppt den {@code Timer}, wenn er derzeit läuft. Die gemessene Dauer wird
* zur Summe aller gemessenen Zeiten hinzuaddiert. * zur Summe aller gemessenen Zeiten hinzuaddiert.
* *
* @return Dieser {@code Timer} selbst (method chaining). * @return Dieser {@code Timer} selbst (method chaining).
@@ -116,8 +116,8 @@ public final class Timer {
/** /**
* Setzt den {@code Timer} auf den Startzustand und löscht alle bisher * Setzt den {@code Timer} auf den Startzustand und löscht alle bisher
* gemessenen Zeiten. Falls die Zeitmessung gerade läuft, wird sie nicht * gemessenen Zeiten. Falls die Zeitmessung gerade läuft, stoppt sie nicht,
* gestoppt, sondern läuft vom Zeitpunkt des Aufrufs weiter. * sondern startet vom Zeitpunkt des Aufrufs neu.
* *
* @return Dieser {@code Timer} selbst (method chaining). * @return Dieser {@code Timer} selbst (method chaining).
*/ */

View File

@@ -3,6 +3,9 @@ package schule.ngb.zm.util;
import java.util.Objects; import java.util.Objects;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* Statische Methoden, um Methodenparameter auf Gültigkeit zu prüfen.
*/
@SuppressWarnings( "UnusedReturnValue" ) @SuppressWarnings( "UnusedReturnValue" )
public class Validator { public class Validator {

View File

@@ -4,37 +4,63 @@ import schule.ngb.zm.util.Log;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.function.Function;
/**
* Helferklasse, um Textdateien in verschiedenen Formaten einzulesen.
*/
@SuppressWarnings( "unused" )
public final class FileLoader { public final class FileLoader {
/**
* Charset: ASCII
*/
public static final Charset ASCII = StandardCharsets.US_ASCII; public static final Charset ASCII = StandardCharsets.US_ASCII;
/**
* Charset: UTF-8
*/
public static final Charset UTF8 = StandardCharsets.UTF_8; public static final Charset UTF8 = StandardCharsets.UTF_8;
/**
* Charset: UTF-16
*/
public static final Charset UTF16 = StandardCharsets.UTF_16; public static final Charset UTF16 = StandardCharsets.UTF_16;
/**
* Charset: ISO-8859-1
*/
public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1; public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1;
/**
* Lädt die angegebene Textdatei zeilenweise in eine Liste.
* <p>
* Als {@link Charset} wird {@link #UTF8} verwendet.
*
* @param source Die Quelle der Textdatei.
* @return Eine Liste mit den Zeilen der Textdatei.
* @see #loadLines(String, Charset)
*/
public static List<String> loadLines( String source ) { public static List<String> loadLines( String source ) {
return loadLines(source, UTF8); return loadLines(source, UTF8);
} }
/** /**
* Lädt die angegebene Datei Zeilenweise in eine Liste. * Lädt die angegebene Textdatei mit dem angegebenen Charset zeilenweise in
* eine Liste.
* <p>
* Am Ende jeder Zeile wird das Symbol für einen Zeilenumbruch ({@code \n})
* entfernt.
* *
* @param source * @param source Die Quelle der Textdatei.
* @param charset * @param charset Das zu verwendene {@code Charset}.
* @return * @return Eine Liste mit den Zeilen der Textdatei.
*/ */
public static List<String> loadLines( String source, Charset charset ) { public static List<String> loadLines( String source, Charset charset ) {
try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) { try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) {
@@ -52,10 +78,28 @@ public final class FileLoader {
} }
} }
/**
* Lädt den Inhalt der angegebenen Textdatei vollständig in einen String.
* <p>
* Als {@link Charset} wird {@link #UTF8} verwendet.
*
* @param source Eine Quelle für die Textdatei (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkressource)
* @return Der Inhalt der Textdatei.
*/
public static String loadText( String source ) { public static String loadText( String source ) {
return loadText(source, UTF8); return loadText(source, UTF8);
} }
/**
* Lädt den Inhalt der angegebenen Textdatei mit dem angegebenen
* {@code Charset} vollständig in einen String.
*
* @param source Eine Quelle für die Textdatei (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkressource)
* @param charset Der {@code Charset} der Textdatei.
* @return Der Inhalt der Textdatei.
*/
public static String loadText( String source, Charset charset ) { public static String loadText( String source, Charset charset ) {
try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) { try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
@@ -73,15 +117,16 @@ public final class FileLoader {
} }
/** /**
* Lädt die Daten aus einer CSV Datei in ein zweidimensionales * Lädt die Daten aus einer CSV-Datei in ein zweidimensionales
* String-Array. * String-Array.
* <p> * <p>
* Der Aufruf entspricht dem Aufruf von * Der Aufruf entspricht
* <pre><code> * <pre><code>
* FileLoader.loadCsv(source, ',', skipFirst, UTF8); * FileLoader.loadCsv(source, ',', skipFirst, UTF8);
* </code></pre> * </code></pre>
* *
* @param source Die Quelle der CSV-Daten. * @param source Eine Quelle für die CSV-Datei (Absoluter Dateipfad,
* * Dateipfad im Classpath oder Netzwerkressource)
* @param skipFirst Ob die erste Zeile übersprungen werden soll. * @param skipFirst Ob die erste Zeile übersprungen werden soll.
* @return Ein Array mit den Daten als {@code String}s. * @return Ein Array mit den Daten als {@code String}s.
* @see #loadCsv(String, char, boolean, Charset) * @see #loadCsv(String, char, boolean, Charset)
@@ -91,12 +136,12 @@ public final class FileLoader {
} }
/** /**
* Lädt die Daten aus einer CSV Datei in ein zweidimensionales * Lädt die Daten aus einer CSV-Datei in ein zweidimensionales
* String-Array. * String-Array.
* <p> * <p>
* Die Methode ist nicht in der Lage, komplexe CSV-Dateien zu verarbeiten. * Die Methode ist nicht in der Lage, komplexe CSV-Dateien zu verarbeiten.
* Insbesondere können Inhalte, die das Trennzeichen {@code separator} * Insbesondere werden Inhalte, die das Trennzeichen {@code separator}
* enthalten, nicht korrekt erkannt werden. Das Trennzeichen wird unabhängig * enthalten, nicht korrekt erkannt. Das Trennzeichen wird unabhängig
* vom Kontext immer als Zelltrenner erkannt. (Im Normalfall kann das * vom Kontext immer als Zelltrenner erkannt. (Im Normalfall kann das
* Trennzeichen durch die Verwendung doppelter Anführungszeichen in der Art * Trennzeichen durch die Verwendung doppelter Anführungszeichen in der Art
* {@code Inhalt,"Inhalt, der Komma enthält",Inhalt} maskiert werden.) * {@code Inhalt,"Inhalt, der Komma enthält",Inhalt} maskiert werden.)

View File

@@ -13,39 +13,38 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
/** /**
* Helferklasse, um {@link InputStream}s für Resourcen zu erhalten. * Helferklasse, um {@link InputStream}s für Ressourcen zu erhalten.
*/ */
@SuppressWarnings("unused")
public class ResourceStreamProvider { public class ResourceStreamProvider {
/** /**
* Ermittelt zur angegebenen Quelle einen passenden {@link URL} (<em>Unified * Ermittelt zur angegebenen Quelle einen passenden {@link URL} (<em>Unified
* Resource Locator</em>). Eine passende Datei-Resource wird wie folgt * Resource Locator</em>). Eine passende Datei-Ressource wird wie folgt
* ermittelt: * ermittelt:
* <ol> * <ol>
* <li>Ist {@code source} eine existierende Datei * <li>Ist {@code source} eine existierende Datei
* ({@code new File(source}.isFile() == true})?</li> * ({@code new File(source}.isFile() == true})?</li>
* <li>Ist {@code source} ein relativer Pfad im Projekt ({@code getResource(source) != null})?.</li> * <li>Ist {@code source} ein relativer Pfad im Projekt ({@code getResource(source) != null})?</li>
* <li>Ist {@code source} im Classpath enthalten ({@code getClassLoader().getResource(source) != null})?</li> * <li>Ist {@code source} im Classpath enthalten ({@code getClassLoader().getResource(source) != null})?</li>
* <li>Ansonten erstellt ein {@link URL}-Objekt.</li> * <li>Ansonsten erstelle ein {@link URL}-Objekt.</li>
* </ol> * </ol>
* <p> * <p>
* Ein {@code URL} für die erste gefundene Resource wird zurückgegeben. * Ein {@code URL} für die erste gefundene Resource wird zurückgegeben.
* Auftretende Exceptions
* werden als {@link IOException} geworfen.
* <p> * <p>
* Bei einer Exception werden die folgenden Quellen nicht mehr abgefragt. * Auftretende Exceptions werden als {@link IOException} geworfen.
* Bei einer Exception werden die nachfolgenden Quellen nicht mehr abgefragt.
* Eine {@link java.net.MalformedURLException} beim Konstruieren des {@code URL} * Eine {@link java.net.MalformedURLException} beim Konstruieren des {@code URL}
* zu einer Datei verhindert daher, dass noch im Classpath gesucht wird. * zu einer Datei verhindert daher, dass noch im Classpath gesucht wird.
* *
* @param source Eine Quelle für die Resource (Absoluter Dateipfad, * @param source Eine Quelle für die Ressource (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkresource) * Dateipfad im Classpath oder Netzwerkressource)
* @return Ein {@code InputStream} für die Resource * @return Ein {@code InputStream} für die Ressource
* @throws NullPointerException Falls {@code source} {@code null} ist. * @throws NullPointerException Falls {@code source} {@code null} ist.
* @throws IllegalArgumentException Falls {@code source} ein leerer String * @throws IllegalArgumentException Falls {@code source} ein leerer String
* ist. * ist.
* @throws IOException Geworfen beim Erzeugen einer URL zu * @throws IOException Geworfen beim Erzeugen einer URL zu
* einer bestehenden Resource. * einer bestehenden Ressource.
*/ */
public static URL getResourceURL( String source ) throws NullPointerException, IllegalArgumentException, IOException { public static URL getResourceURL( String source ) throws NullPointerException, IllegalArgumentException, IOException {
Validator.requireNotNull(source, "Resource source may not be null"); Validator.requireNotNull(source, "Resource source may not be null");
@@ -66,50 +65,59 @@ public class ResourceStreamProvider {
} }
/** /**
* Sucht eine zur angegebenen Quelle passende Resource und öffnet einen * Sucht eine zur angegebenen Quelle passende Ressource und öffnet einen
* passenden {@link InputStream}. Die konkrete Art des Streams hängt davon * passenden {@link InputStream}. Die konkrete Art des Streams hängt davon
* ab, welche Art an Resource gefunden wird: * ab, welche Art an Ressource gefunden wird:
* <ol> * <ol>
* <li>Ist {@code source} eine existierende Datei * <li>Ist {@code source} eine existierende Datei
* {@code new File(source}.isFile() == true}, dann wird ein * {@code new File(source).isFile() == true}, dann wird ein
* {@link FileInputStream} erstellt.</li> * {@link FileInputStream} erstellt.</li>
* <li>Ist {@code source} ein relativer Pfad im Projekt, wird ein passender * <li>Ist {@code source} ein relativer Pfad im Projekt, wird ein passender
* Stream mit {@link Class#getResourceAsStream(String)} geöffnet.</li> * Stream mit {@link Class#getResourceAsStream(String)} geöffnet.</li>
* <li>Ist {@code source} im Classpath enthalten, wird ein passender Stream * <li>Ist {@code source} im Classpath enthalten, wird ein passender Stream
* mit {@link ClassLoader#getResourceAsStream(String)} geöffnet.</li> * mit {@link ClassLoader#getResourceAsStream(String)} geöffnet.</li>
* <li>Ist {@code source} eine gültige {@link URL}, dann wird ein * <li>Ist {@code source} eine gültige {@link URL}, dann wird ein
* {@link URL#openStream() Netwerkstream} geöffnet.</li> * {@link URL#openStream() Netwerkstream} geöffnet.</li>
* </ol> * </ol>
* <p> * <p>
* Die Möglichen Resourcen werden in der gelisteten Reihenfolge durchprobiert * Die Möglichen Ressourcen werden in der gelisteten Reihenfolge durchprobiert
* und der erste gefundene Stream zurückgegeben. Auftretende Exceptions * und der erste gefundene Stream zurückgegeben. Auftretende Exceptions
* werden als {@link IOException} geworfen. Das bedeutet, falls für {@code source} * werden als {@link IOException} geworfen. Das bedeutet, falls für {@code source}
* keine gültige Resource gefunden werden kann, wird am Ende die * keine gültige Ressource gefunden werden kann, wird am Ende die
* von {@link URL#openStream()} erzeugte {@code IOException} geworfen. * von {@link URL#openStream()} erzeugte {@code IOException} geworfen.
* <p> * <p>
* Bei einer Exception werden die folgenden Quellen nicht mehr abgefragt. * Bei einer Exception werden die nachfolgenden Quellen nicht mehr abgefragt.
* Eine {@link SecurityException} beim Öffnen des {@code FileInputStream} * Eine {@link SecurityException} beim Öffnen des {@code FileInputStream}
* (zum Beispiel, weil auf eine existierende Datei keine Leserechte bestehen) * (zum Beispiel, weil auf eine existierende Datei keine Leserechte bestehen)
* verhindert daher, dass noch im Classpath gesucht wird. * verhindert daher, dass noch im Classpath gesucht wird.
* *
* @param source Eine Quelle für die Resource (Absoluter Dateipfad, * @param source Eine Quelle für die Ressource (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkresource) * Dateipfad im Classpath oder Netzwerkresource).
* @return Ein {@code InputStream} für die Resource * @return Ein {@code InputStream} für die Ressource.
* @throws NullPointerException Falls {@code source} {@code null} ist. * @throws NullPointerException Falls {@code source} {@code null} ist.
* @throws IllegalArgumentException Falls {@code source} ein leerer String * @throws IllegalArgumentException Falls {@code source} ein leerer String
* ist. * ist.
* @throws IOException Geworfen beim Öffnen des Streams zu * @throws IOException Geworfen beim Öffnen des Streams zu
* einer bestehenden Resource oder falls * einer bestehenden Ressource oder falls
* keine passende Resource gefunden wurde. * keine passende Ressource gefunden
* wurde.
*/ */
public static InputStream getInputStream( String source ) throws NullPointerException, IllegalArgumentException, IOException { public static InputStream getInputStream( String source ) throws NullPointerException, IllegalArgumentException, IOException {
return getResourceURL(source).openStream(); return getResourceURL(source).openStream();
} }
/** /**
* @param source * Sucht eine zur angegebenen Quelle passende Ressource und öffnet einen
* @return * passenden {@link OutputStream}.
* @throws IOException * <p>
* Es wird davon ausgegangen, dass die Quelle auf eine Datei verweist, auf
* die Schreibrechte bestehen. Ist dies nicht der Fall, wird eine
* {@link IOException} geworfen.
*
* @param source Eine Quelle für die Ressource (Absoluter Dateipfad,
* Dateipfad im Classpath).
* @return {@code OutputStream} für die Ressource.
* @throws IOException Falls die Quelle kein gültiges Ziel beschreibt.
*/ */
public static OutputStream getOutputStream( String source ) throws IOException { public static OutputStream getOutputStream( String source ) throws IOException {
try { try {
@@ -119,22 +127,83 @@ public class ResourceStreamProvider {
} }
} }
/**
* Sucht eine zur angegebenen Quelle passende Ressource und öffnet einen
* {@link BufferedReader}.
* <p>
* Die Suche erfolgt, wie bei {@link #getInputStream(String)} beschrieben.
* <p>
* Als {@link Charset} wird {@link StandardCharsets#UTF_8 UTF-8} verwendet.
*
* @param source Eine Quelle für die Ressource (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkresource).
* @return Ein {@code BufferedReader} für die Quelle.
* @throws IOException Falls die Quelle nicht exisitert oder nicht geöffnet
* werden kann.
* @see #getInputStream(String)
*/
public static BufferedReader getReader( String source ) throws IOException { public static BufferedReader getReader( String source ) throws IOException {
return getReader(source, StandardCharsets.UTF_8); return getReader(source, StandardCharsets.UTF_8);
} }
/**
* Sucht eine zur angegebenen Quelle passende Ressource und öffnet einen
* {@link BufferedReader} mit dem angegebenen Charset.
* <p>
* Die Suche erfolgt wie bei {@link #getInputStream(String)} beschrieben.
*
* @param source Eine Quelle für die Ressource (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkresource).
* @param charset Der zu verwendende Charset.
* @return Ein {@code BufferedReader} für die Quelle.
* @throws IOException Falls die Quelle nicht exisitert oder nicht geöffnet
* werden kann.
* @see #getInputStream(String)
*/
public static BufferedReader getReader( String source, Charset charset ) throws IOException { public static BufferedReader getReader( String source, Charset charset ) throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream(source), charset.newDecoder())); return new BufferedReader(new InputStreamReader(getInputStream(source), charset.newDecoder()));
} }
/**
* Sucht eine zur angegebenen Quelle passende Datei und öffnet einen
* {@link BufferedWriter}.
* <p>
* Die Suche erfolgt wie bei {@link #getOutputStream(String)} beschrieben.
* <p>
* Als {@link Charset} wird {@link StandardCharsets#UTF_8 UTF-8} verwendet.
*
* @param source Eine Quelle für die Ressource (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkresource).
* @return Ein {@code BufferedWriter} für die Quelle.
* @throws IOException Falls die Quelle nicht exisitert oder nicht geöffnet
* werden kann.
* @see #getOutputStream(String)
*/
public static BufferedWriter getWriter( String source ) throws IOException { public static BufferedWriter getWriter( String source ) throws IOException {
return getWriter(source, StandardCharsets.UTF_8); return getWriter(source, StandardCharsets.UTF_8);
} }
/**
* Sucht eine zur angegebenen Quelle passende Datei und öffnet einen
* {@link BufferedWriter}.
* <p>
* Die Suche erfolgt wie bei {@link #getOutputStream(String)} beschrieben.
* <p>
* Als {@link Charset} wird {@link StandardCharsets#UTF_8 UTF-8} verwendet.
*
* @param source Eine Quelle für die Ressource (Absoluter Dateipfad,
* Dateipfad im Classpath oder Netzwerkresource).
* @return Ein {@code BufferedWriter} für die Quelle.
* @param charset Der zu verwendende Charset.
* @throws IOException Falls die Quelle nicht exisitert oder nicht geöffnet
* werden kann.
* @see #getOutputStream(String)
*/
public static BufferedWriter getWriter( String source, Charset charset ) throws IOException { public static BufferedWriter getWriter( String source, Charset charset ) throws IOException {
return new BufferedWriter(new OutputStreamWriter(getOutputStream(source), charset.newEncoder())); return new BufferedWriter(new OutputStreamWriter(getOutputStream(source), charset.newEncoder()));
} }
// Privater C'tor
private ResourceStreamProvider() { private ResourceStreamProvider() {
} }