Skip to contentMethod: isEmpty()
1: package cz.cvut.kbss.jopa.model;
2:
3: import java.io.Serializable;
4: import java.util.*;
5:
6: /**
7: * Represents a string with translations to (possibly) multiple languages.
8: * <p>
9: * This allows an application to naturally work in an internationalized environment leveraging the <a
10: * href="https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string">language-tagged strings</a> of the Semantic
11: * Web.
12: * <p>
13: * Instances of this class basically represent all available translations of the string, allowing to read (and write)
14: * particular versions by specifying the corresponding language tag. A special case supported by this class are <a
15: * href="https://www.w3.org/TR/rdf11-concepts/#section-Graph-Literal">simple literals</a> (language-less strings with
16: * type {@code xsd:string}), for which the language tag is {@code null}.
17: * <p>
18: * Note that this class is not thread-safe.
19: */
20: public class MultilingualString implements Serializable {
21:
22: private final Map<String, String> value;
23:
24: public MultilingualString() {
25: this.value = new HashMap<>(8);
26: }
27:
28: /**
29: * Creates a new {@code MultilingualString} instance based on the specified value.
30: * <p>
31: * Convenience constructor for simple initialization with existing data.
32: *
33: * @param value Map of language to translation values
34: */
35: public MultilingualString(Map<String, String> value) {
36: this.value = new HashMap<>(Objects.requireNonNull(value));
37: }
38:
39: /**
40: * Sets value in the specified language.
41: * <p>
42: * This overrides any previous value in the specified language, if it existed.
43: *
44: * @param language Language to use with the specified value. Passing {@code null} has the same effect as {@link
45: * #set(String)}
46: * @param value String value in the specified language
47: * @see #set(String)
48: */
49: public void set(String language, String value) {
50: Objects.requireNonNull(value);
51: this.value.put(language, value);
52: }
53:
54: /**
55: * Sets value without language.
56: * <p>
57: * That is, the specified value will be stored as a simple literal (type xsd:string).
58: *
59: * @param value Value to set
60: * @see #set(String, String)
61: */
62: public void set(String value) {
63: Objects.requireNonNull(value);
64: this.value.put(null, value);
65: }
66:
67: /**
68: * Gets value for the specified language.
69: * <p>
70: * If no language is specified, either the simple literal value is returned (if present), or any other existing
71: * value is returned. However, note that, in case of missing simple literal, repeated calls may return values in
72: * different languages. If there are no translations, {@code null} is returned.
73: *
74: * @param language Requested language (language tag). Can be {@code null}
75: * @return Value of this string for the specified language (or {@code null} if not available)
76: */
77: public String get(String language) {
78: return language != null ? value.get(language) : get();
79: }
80:
81: /**
82: * Gets the value of a simple literal represented by this instance.
83: * <p>
84: * If this instances does not represent a simple literal, any other existing value is returned. However, note that
85: * in that case repeated calls may return values in different languages.
86: * <p>
87: * If this object is empty (i.e., neither simple literal nor any translations are available), {@code null} is
88: * returned.
89: *
90: * @return Value of simple literal represented by this string
91: */
92: public String get() {
93: return value.getOrDefault(null, value.isEmpty() ? null : value.get(value.keySet().iterator().next()));
94: }
95:
96: /**
97: * Checks whether this string contains value in the specified language.
98: * <p>
99: * If no language is specified (argument is {@code null}), this method will return {@code true} if there is value
100: * without language tag (simple literal) or in any other language.
101: *
102: * @param language Requested language (language tag)
103: * @return {@code true} if this string exists in the specified language
104: */
105: public boolean contains(String language) {
106: return value.containsKey(language) || (language == null && !value.isEmpty());
107: }
108:
109: /**
110: * Checks whether this string contains a simple literal value.
111: * <p>
112: * That is, whether this instance contains a value without a language tag.
113: *
114: * @return {@code true} if and only if this string exists as a simple literal
115: */
116: public boolean containsSimple() {
117: return value.containsKey(null);
118: }
119:
120: /**
121: * Checks whether this instance does not contain any language representations (including a simple literal).
122: *
123: * @return {@code true} if no translations exist in this instance
124: */
125: public boolean isEmpty() {
126: return value.isEmpty();
127: }
128:
129: /**
130: * Removes translation in the specified language.
131: * <p>
132: * Passing in {@code null} will remove the simple literal contained in this instance.
133: *
134: * @param language Language for which translation should be removed
135: */
136: public void remove(String language) {
137: value.remove(language);
138: }
139:
140: /**
141: * Gets the set of languages for which translations exist in the instance.
142: * <p>
143: * Note that the result may contain {@code null}, indicating a simple literal.
144: *
145: * @return Set of languages available in this multilingual string
146: */
147: public Set<String> getLanguages() {
148: return Collections.unmodifiableSet(value.keySet());
149: }
150:
151: /**
152: * Gets the translations contained in this instance as an unmodifiable map backed by this instance.
153: * <p>
154: * Convenience method for accessing all values at once.
155: *
156: * @return Map of language to translation values
157: */
158: public Map<String, String> getValue() {
159: return Collections.unmodifiableMap(value);
160: }
161:
162: @Override
163: public boolean equals(Object o) {
164: if (this == o) {
165: return true;
166: }
167: if (!(o instanceof MultilingualString)) {
168: return false;
169: }
170: MultilingualString that = (MultilingualString) o;
171: return value.equals(that.value);
172: }
173:
174: @Override
175: public int hashCode() {
176: return Objects.hash(value);
177: }
178:
179: @Override
180: public String toString() {
181: return value.toString();
182: }
183:
184: /**
185: * Creates a new instance of {@link MultilingualString} and sets the specified value in the specified language.
186: * <p>
187: * Convenience method for creating strings with one (initial) translation.
188: *
189: * @param value String value
190: * @param language Language of the value (language tag)
191: * @return New instance of {@code MultiLangString}
192: */
193: public static MultilingualString create(String value, String language) {
194: final MultilingualString instance = new MultilingualString();
195: instance.set(language, value);
196: return instance;
197: }
198: }