EnglishWordsInstance.java
package net.morimekta.testing.text;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.ThreadLocalRandom.current;
/**
* This is a very light-weight version of fairy, which just generates
* simple pseudo-sentences in repeated SVO patterns.
*/
class EnglishWordsInstance {
public String noun() {
return requireNonNull(nouns.get(current().nextInt(nouns.size())));
}
public String thing() {
if (current().nextBoolean()) {
return adjective() + " " + noun();
}
return noun();
}
public String adjective() {
return requireNonNull(adjectives.get(current().nextInt(adjectives.size())));
}
public String verb() {
return requireNonNull(verbs.get(current().nextInt(verbs.size())));
}
public String word() {
return requireNonNull(words.get(current().nextInt(words.size())));
}
public String sentence(int minLength) {
StringBuilder sentence = new StringBuilder();
while (sentence.length() < minLength) {
if (sentence.length() > 0) {
sentence.append(", and ")
.append(thing());
} else {
sentence.append(capitalize(thing()));
}
sentence.append(" ")
.append(verb())
.append(" ")
.append(thing());
}
return sentence.toString();
}
public String paragraph(int sentences) {
return IntStream.range(0, sentences)
.sequential()
.map(i -> current().nextInt(50) + 20)
.mapToObj(this::sentence)
.collect(Collectors.joining(". ")) + ".";
}
// --- Protected ---
static EnglishWordsInstance getInstance() {
return INSTANCE.updateAndGet(i -> {
if (i == null) {
i = new EnglishWordsInstance();
}
return i;
});
}
// --- Private ---
private static final System.Logger LOGGER =
System.getLogger(EnglishWordsInstance.class.getName());
private static final AtomicReference<EnglishWordsInstance> INSTANCE =
new AtomicReference<>();
private final List<String> nouns;
private final List<String> adjectives;
private final List<String> verbs;
private final List<String> words;
private EnglishWordsInstance() {
try (InputStream in = requireNonNull(
EnglishWordsInstance.class.getResourceAsStream("/net/morimekta/testing/text/words.txt"),
"in == null");
InputStreamReader reader = new InputStreamReader(in, UTF_8);
BufferedReader bufferedReader = new BufferedReader(reader);
Stream<String> lines = requireNonNull(bufferedReader.lines(), "line == null")) {
List<String> nounsB = new ArrayList<>();
List<String> adjectivesB = new ArrayList<>();
List<String> verbsB = new ArrayList<>();
List<String> wordsB = new ArrayList<>();
lines.forEach(line -> {
String[] word = line.split(" ", 3);
if (word.length != 3 || word[0].isEmpty()) {
return;
} else if (word[2].contains("adjective")) {
adjectivesB.add(word[0]);
} else if (word[2].contains("verb")) {
verbsB.add(word[0]);
} else if (word[2].contains("noun")) {
nounsB.add(word[0]);
}
wordsB.add(word[0]);
});
nouns = List.copyOf(nounsB);
adjectives = List.copyOf(adjectivesB);
verbs = List.copyOf(verbsB);
words = List.copyOf(wordsB);
} catch (IOException e) {
LOGGER.log(System.Logger.Level.ERROR, "Failed to load words: " + e.getMessage(), e);
throw new UncheckedIOException(e.getMessage(), e);
}
}
private static String capitalize(String word) {
return word.substring(0, 1).toUpperCase(Locale.US) + word.substring(1);
}
}