org.daisy.dotify.api.translator.TranslatableWithContext Maven / Gradle / Ivy
package org.daisy.dotify.api.translator;
import java.util.List;
import java.util.Optional;
/**
* Provides a specification for a list of texts to translate.
* This class is best suited for use cases where the input is
* naturally segmented and contains some segments with dynamic content
* (in other words, content that may change after it has been
* submitted to a {@link BrailleTranslator} or a {@link BrailleFilter}).
*
* This class has the following characteristics:
*
* - it applies to a list of text segments
* - style attributes apply to whole segments only
* - style attributes may span more than one instance of {@link TranslatableWithContext}
* - a segment can have a content size that is unknown when the translatable is created
* - it provides information about the context of the text segments to translate
*
*
* @author Joel Håkansson
* @see Translatable
*/
public class TranslatableWithContext {
private final TextWithContext texts;
private final Optional attributes;
/**
* Provides a builder for translatable objects.
*
* @author Joel Håkansson
*/
public static class Builder {
private final TextWithContext texts;
private AttributeWithContext attributes = null;
private Builder(TextWithContext texts) {
this.texts = texts;
}
/**
* Sets the attribute context for this builder.
*
* @param value the attribute context
* @return this object
*/
public Builder attributes(AttributeWithContext value) {
this.attributes = value;
return this;
}
/**
* Builds a new Translatable object using the current
* status of this builder.
*
* @return a Translatable instance
*/
public TranslatableWithContext build() {
return new TranslatableWithContext(this);
}
}
private TranslatableWithContext(Builder builder) {
this.texts = builder.texts;
this.attributes = Optional.ofNullable(builder.attributes);
}
/**
* Creates a new Translatable.Builder with the specified text.
*
* @param texts the text to translate
* @return a new Translatable.Builder
*/
public static Builder text(TextWithContext texts) {
return new Builder(texts);
}
/**
* Returns a new Translatable builder for this list.
* The current item is the specified index
.
*
* @param list the list
* @param index the index of the current item
* @param the type of items
* @return a new context
* @throws IndexOutOfBoundsException for an illegal endpoint index value
* (fromIndex < 0 || toIndex > size ||
* fromIndex > toIndex
)
*/
public static Builder from(List list, int index) {
return new Builder(newContext(list, index));
}
/**
* Returns a new Translatable builder for this list.
* The current items are between the specified fromIndex
,
* inclusive, and toIndex
, exclusive. (If
* fromIndex
and toIndex
are equal, the current items list
* is empty, however this isn't useful in practice.)
*
* @param list the list
* @param fromIndex low endpoint (inclusive) of the current subList
* @param toIndex high endpoint (exclusive) of the current subList
* @param the type of items
* @return a new context
* @throws IndexOutOfBoundsException for an illegal endpoint index value
* (fromIndex < 0 || toIndex > size ||
* fromIndex > toIndex
)
*/
public static Builder from(List list, int fromIndex, int toIndex) {
return new Builder(newContext(list, fromIndex, toIndex));
}
/**
* Returns a context for this list where the current item is at the specified
* index
.
*
* See {@link #newContext(int, int)} for more information about the returned
* lists.
*
* @param list the list
* @param index the index of the current item
* @param the type of resolvable
* @return a new context
* @throws IndexOutOfBoundsException for an illegal endpoint index value
* (fromIndex < 0 || toIndex > size ||
* fromIndex > toIndex
)
*/
static TextWithContext newContext(List list, int index) {
return newContext(list, index, index + 1);
}
/**
* Returns a context for this list where the current items are between the specified
* fromIndex
, inclusive, and toIndex
, exclusive. (If
* fromIndex
and toIndex
are equal, the current items list
* is empty, however this isn't useful in practice.)
*
* The returned list is backed by the original list, so non-structural
* changes in the returned list are reflected in this list, and vice-versa.
*
* The semantics of the lists returned by this method become undefined if
* the backing list is structurally modified in
* any way other than via the returned lists. (Structural modifications are
* those that change the size of this list, or otherwise perturb it in such
* a fashion that iterations in progress may yield incorrect results.)
*
* @param list the list
* @param fromIndex low endpoint (inclusive) of the current subList
* @param toIndex high endpoint (exclusive) of the current subList
* @param the type of resolvable
* @return a new context
* @throws IndexOutOfBoundsException for an illegal endpoint index value
* (fromIndex < 0 || toIndex > size ||
* fromIndex > toIndex
)
*/
static TextWithContext newContext(List list, int fromIndex, int toIndex) {
return new TextWithContext() {
private final List extends PrecedingText> preceding = list.subList(0, fromIndex);
private final List extends FollowingText> following = list.subList(toIndex, list.size());
private final List extends ResolvableText> current = list.subList(fromIndex, toIndex);
@SuppressWarnings("unchecked")
@Override
public List getPrecedingText() {
return (List) preceding;
}
@SuppressWarnings("unchecked")
@Override
public List getFollowingText() {
return (List) following;
}
@SuppressWarnings("unchecked")
@Override
public List getTextToTranslate() {
return (List) current;
}
};
}
/**
* Gets the text items in the context that preceded
* the current text. The preceding text may have been
* translated with the same translator, or it may have been
* translated with another translator.
*
* @return the preceding text items
*/
public List getPrecedingText() {
return texts.getPrecedingText();
}
/**
* Gets the text items in the context that follows
* the current text. The following text may be translated
* with the same translator, or it may be translated with
* another translator.
*
* @return the following text items
*/
public List getFollowingText() {
return texts.getFollowingText();
}
/**
* Gets the text items to translate.
*
* @return the text to translate
*/
public List getTextToTranslate() {
return texts.getTextToTranslate();
}
/**
* Gets the attribute context.
*
* @return the attribute context
*/
public Optional getAttributes() {
return attributes;
}
}