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 }