001 // This file is part of AceWiki.
002 // Copyright 2008-2012, AceWiki developers.
003 //
004 // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005 // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006 // the License, or (at your option) any later version.
007 //
008 // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010 // Lesser General Public License for more details.
011 //
012 // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013 // not, see http://www.gnu.org/licenses/.
014
015 package ch.uzh.ifi.attempto.base;
016
017 import java.util.ArrayList;
018 import java.util.List;
019
020 /**
021 * This class represents a text container that stores a sequence of text elements that represent a
022 * (partial) text or sentence.
023 *
024 * @author Tobias Kuhn
025 */
026 public class TextContainer {
027
028 private List<TextElement> elements = new ArrayList<TextElement>();
029 private TextOperator textOperator = new DefaultTextOperator();
030
031 /**
032 * Creates a new text container.
033 */
034 public TextContainer() {
035 }
036
037 /**
038 * Creates a new text container using the given text operator.
039 *
040 * @param textOperator The text operator to be used.
041 */
042 public TextContainer(TextOperator textOperator) {
043 setTextOperator(textOperator);
044 }
045
046 /**
047 * Creates a new text container that contains the given text elements.
048 *
049 * @param elements The elements to be added to the new text container.
050 */
051 public TextContainer(TextElement... elements) {
052 for (TextElement el : elements) {
053 addElement(el);
054 }
055 }
056
057 /**
058 * Creates a new text container that uses the given text operator and that contains the
059 * given text elements.
060 *
061 * @param textOperator The text operator to be used.
062 * @param elements The elements to be added to the new text container.
063 */
064 public TextContainer(TextOperator textOperator, TextElement... elements) {
065 for (TextElement el : elements) {
066 addElement(el);
067 }
068 setTextOperator(textOperator);
069 }
070
071 /**
072 * Returns the number of text elements of this text container.
073 *
074 * @return The number of text elements.
075 */
076 public int getTextElementsCount() {
077 return elements.size();
078 }
079
080 /**
081 * Returns the text element with the given index.
082 * @param index The index of the text element to be returned.
083 * @return The text element.
084 */
085 public TextElement getTextElement(int index) {
086 return elements.get(index);
087 }
088
089 /**
090 * Returns the sequence of text elements.
091 *
092 * @return A list containing the text elements.
093 */
094 public List<TextElement> getTextElements() {
095 return new ArrayList<TextElement>(elements);
096 }
097
098 /**
099 * Sets the text elements.
100 * @param elements A list of text elements.
101 */
102 public void setTextElements(List<TextElement> elements) {
103 this.elements = new ArrayList<TextElement>(elements);
104 }
105
106 /**
107 * Adds the text element to the end of the sequence.
108 *
109 * @param el The text element to be added.
110 */
111 public void addElement(TextElement el) {
112 el.setTextContainer(this);
113 elements.add(el);
114 }
115
116 /**
117 * Removes all text elements.
118 */
119 public void removeAllElements() {
120 for (TextElement te : elements) te.removeTextContainer();
121 elements.clear();
122 }
123
124 /**
125 * Removes the last text element of the sequence if it is not empty.
126 */
127 public void removeLastElement() {
128 if (elements.size() > 0) {
129 int last = elements.size() - 1;
130 elements.get(last).removeTextContainer();
131 elements.remove(last);
132 }
133 }
134
135 /**
136 * Returns the text that is represented by the sequence of text element as a string.
137 *
138 * @return The text.
139 */
140 public String getText() {
141 String text = "";
142 TextElement prev = null;
143 for (TextElement e : elements) {
144 if (prev != null) {
145 text += textOperator.getGlue(prev, e) + e.getText();
146 } else {
147 text += e.getText();
148 }
149 prev = e;
150 }
151 return text;
152 }
153
154 /**
155 * Sets the text operator.
156 *
157 * @param textOperator The new text operator.
158 */
159 public void setTextOperator(TextOperator textOperator) {
160 this.textOperator = textOperator;
161 }
162
163 /**
164 * Returns the text operator of this text container.
165 *
166 * @return The text operator.
167 */
168 public TextOperator getTextOperator() {
169 return textOperator;
170 }
171
172 /**
173 * Returns the position of the given text element within this text container or -1 if the
174 * text element is not contained by this text container. Note that the elements are checked for
175 * identity, not for equality.
176 *
177 * @param textElement The text element.
178 * @return The index of the text element.
179 */
180 public int getIndexOf(TextElement textElement) {
181 // indexOf(...) does not work, because it uses the equals-method, but we need to check for
182 // identity:
183 int index = -1;
184 for (int i = 0 ; i < elements.size() ; i++) {
185 if (elements.get(i) == textElement) {
186 index = i;
187 break;
188 }
189 }
190 return index;
191 }
192
193 String getTextElementText(TextElement te) {
194 if (textOperator == null) {
195 return te.getOriginalText();
196 } else {
197 String preceding = null;
198 String following = null;
199 int pos = getIndexOf(te);
200 if (pos > 0) {
201 preceding = elements.get(pos-1).getOriginalText();
202 }
203 if (pos < elements.size()-1) {
204 following = elements.get(pos+1).getOriginalText();
205 }
206 return textOperator.getTextInContext(te, preceding, following);
207 }
208 }
209
210 /**
211 * Returns a new text container containing a subsequence of the elements of this text
212 * container.
213 *
214 * @param startPos The position of the first element.
215 * @param endPos The position after the last element.
216 * @return The new text container.
217 */
218 public TextContainer getSubTextContainer(int startPos, int endPos) {
219 TextContainer subtc = new TextContainer(textOperator);
220 for (int i = startPos; i < endPos; i++) {
221 subtc.addElement(elements.get(i));
222 }
223 return subtc;
224 }
225
226 public TextContainer clone() {
227 TextContainer clone = new TextContainer();
228 clone.elements = new ArrayList<TextElement>(this.elements);
229 clone.textOperator = this.textOperator;
230 return clone;
231 }
232
233 }