Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
Represents a non-localized and user-defined format for timespans based on a
* pattern containing some standard symbols and literals.
*
* @param generic type of time units
* @param generic type of supported timespan
* @since 3.26/4.22
*/
/*[deutsch]
*
Nicht-lokalisiertes benutzerdefiniertes Zeitspannenformat, das auf
* Symbolmustern beruht.
*
* @param generic type of time units
* @param generic type of supported timespan
* @since 3.26/4.22
*/
public abstract class TimeSpanFormatter> {
//~ Statische Felder/Initialisierungen --------------------------------
private static final Object SIGN_KEY = new Object();
//~ Instanzvariablen --------------------------------------------------
private final Class type;
private final List> items;
private final String pattern;
//~ Konstruktoren -----------------------------------------------------
/**
*
Standard constructor for subclasses.
*
* @param type reified unit type
* @param pattern format pattern
* @throws IllegalArgumentException in any case of pattern inconsistencies or failures
*/
/*[deutsch]
*
Standardkonstruktor für Subklassen.
*
* @param type reified unit type
* @param pattern format pattern
* @throws IllegalArgumentException in any case of pattern inconsistencies or failures
*/
protected TimeSpanFormatter(
Class type,
String pattern
) {
super();
if (type == null) {
throw new NullPointerException("Missing unit type.");
}
int n = pattern.length();
List>> stack = new ArrayList<>();
stack.add(new ArrayList<>());
int digits = 0;
for (int i = 0; i < n; i++) {
char c = pattern.charAt(i);
if (c == '#') {
digits++;
} else if (isSymbol(c)) {
int start = i++;
while ((i < n) && pattern.charAt(i) == c) {
i++;
}
this.addSymbol(c, i - start, digits, stack);
digits = 0;
i--;
} else if (digits > 0) {
throw new IllegalArgumentException("Char # must be followed by unit symbol.");
} else if (c == '\'') { // Literalsektion
int start = i++;
while (i < n) {
if (pattern.charAt(i) == '\'') {
if ((i + 1 < n) && (pattern.charAt(i + 1) == '\'')) {
i++;
} else {
break;
}
}
i++;
}
if (i >= n) {
throw new IllegalArgumentException(
"String literal in pattern not closed: " + pattern);
}
if (start + 1 == i) {
this.addLiteral('\'', stack);
} else {
String s = pattern.substring(start + 1, i);
this.addLiteral(s.replace("''", "'"), stack);
}
} else if (c == '[') {
startOptionalSection(stack);
} else if (c == ']') {
endOptionalSection(stack);
} else if (c == '.') {
lastOn(stack).add(new SeparatorItem<>('.', ','));
} else if (c == ',') {
lastOn(stack).add(new SeparatorItem<>(',', '.'));
} else if (c == '-') {
lastOn(stack).add(new SignItem<>(false));
} else if (c == '+') {
lastOn(stack).add(new SignItem<>(true));
} else if (c == '{') {
int start = ++i;
while ((i < n) && pattern.charAt(i) != '}') {
i++;
}
this.addPluralItem(pattern.substring(start, i), stack);
} else if (c == '|') {
lastOn(stack).add(OrItem.getInstance());
} else {
this.addLiteral(c, stack);
}
}
if (stack.size() > 1) {
throw new IllegalArgumentException(
"Open square bracket without closing one.");
} else if (stack.isEmpty()) {
throw new IllegalArgumentException("Empty or invalid pattern.");
}
List> items = stack.get(0);
if (items.isEmpty()) {
throw new IllegalArgumentException("Missing format pattern.");
} else if ((items.get(0) == OrItem.INSTANCE) || (items.get(items.size() - 1) == OrItem.INSTANCE)) {
throw new IllegalArgumentException("Pattern must not start or end with an or-operator.");
}
int count = items.size();
int reserved = items.get(count - 1).getMinWidth();
for (int i = count - 2; i >= 0; i--) {
FormatItem item = items.get(i);
if (item == OrItem.INSTANCE) {
reserved = 0;
} else {
items.set(i, item.update(reserved));
reserved += item.getMinWidth();
}
}
this.type = type;
this.items = Collections.unmodifiableList(items);
this.pattern = pattern;
}
//~ Methoden ----------------------------------------------------------
/**
*
*
* @return Class
*/
public Class getType() {
return this.type;
}
/**
*
Creates a textual output of given duration.
*
* @param duration duration object
* @return textual representation of duration
* @throws IllegalArgumentException if some aspects of duration
* prevents printing (for example too many nanoseconds)
*/
/*[deutsch]
*
Erzeugt eine textuelle Ausgabe der angegebenen Dauer.
*
* @param duration duration object
* @return textual representation of duration
* @throws IllegalArgumentException if some aspects of duration
* prevents printing (for example too many nanoseconds)
*/
public String format(TimeSpan super U> duration) {
StringBuilder buffer = new StringBuilder();
try {
this.print(duration, buffer);
} catch (IOException ex) {
throw new AssertionError(ex); // should never happen
}
return buffer.toString();
}
/**
*
Creates a textual output of given duration and writes to
* the buffer.
*
* @param duration duration object
* @param buffer I/O-buffer where the result is written to
* @throws IllegalArgumentException if some aspects of duration
* prevents printing (for example too many nanoseconds)
* @throws IOException if writing into buffer fails
*/
/*[deutsch]
*
Erzeugt eine textuelle Ausgabe der angegebenen Dauer und
* schreibt sie in den Puffer.
*
* @param duration duration object
* @param buffer I/O-buffer where the result is written to
* @throws IllegalArgumentException if some aspects of duration
* prevents printing (for example too many nanoseconds)
* @throws IOException if writing into buffer fails
*/
public void print(
TimeSpan super U> duration,
Appendable buffer
) throws IOException {
for (FormatItem item : this.items) {
if (item == OrItem.INSTANCE) {
break;
}
item.print(duration, buffer);
}
}
/**
*
Equivalent to {@code parse(text, 0)}.
*
* @param text custom textual representation to be parsed
* @return parsed duration
* @throws ParseException (for example in case of mixed signs)
* @see #parse(CharSequence, int)
*/
/*[deutsch]
*
Äquivalent zu {@code parse(text, 0)}.
*
* @param text custom textual representation to be parsed
* @return parsed duration
* @throws ParseException (for example in case of mixed signs)
* @see #parse(CharSequence, int)
*/
public S parse(CharSequence text) throws ParseException {
return this.parse(text, 0);
}
/**
*
Analyzes given text according to format pattern and parses the
* text to a duration.
*
* @param text custom textual representation to be parsed
* @param offset start position for the parser
* @return parsed duration
* @throws ParseException (for example in case of mixed signs)
*/
/*[deutsch]
*
Interpretiert den angegebenen Text entsprechend dem
* voreingestellten Formatmuster als Dauer.
*
* @param text custom textual representation to be parsed
* @param offset start position for the parser
* @return parsed duration
* @throws ParseException (for example in case of mixed signs)
*/
public S parse(
CharSequence text,
int offset
) throws ParseException {
int pos = offset;
Map