001    // This file is part of the Attempto Java Packages.
002    // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
003    //
004    // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the
005    // terms of the GNU Lesser General Public License as published by the Free Software Foundation,
006    // either version 3 of the License, or (at your option) any later version.
007    //
008    // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY
009    // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
010    // PURPOSE. See the GNU Lesser General Public License for more details.
011    //
012    // You should have received a copy of the GNU Lesser General Public License along with the Attempto
013    // Java Packages. If not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.preditor.text;
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 ArrayList<TextElement> elements = new ArrayList<TextElement>();
029            private ContextChecker contextChecker;
030            
031            /**
032             * Creates a new text container.
033             */
034            public TextContainer() {
035            }
036            
037            /**
038             * Creates a new text container using the given context checker.
039             * 
040             * @param contextChecker The context checker to be used.
041             */
042            public TextContainer(ContextChecker contextChecker) {
043                    setContextChecker(contextChecker);
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 context checker and that contains the
059             * given text elements.
060             * 
061             * @param contextChecker The context checker to be used.
062             * @param elements The elements to be added to the new text container.
063             */
064            public TextContainer(ContextChecker contextChecker, TextElement... elements) {
065                    for (TextElement el : elements) {
066                            addElement(el);
067                    }
068                    setContextChecker(contextChecker);
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 ArrayList<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                    for (TextElement e : elements) {
143                            if (e.getText().matches("[.?!]")) {
144                                    text += e.getText();
145                            } else {
146                                    text += " " + e.getText();
147                            }
148                    }
149                    if (text.startsWith(" ")) {
150                            text = text.substring(1);
151                    }
152                    return text;
153            }
154            
155            /**
156             * Sets the context checker.
157             * 
158             * @param contextChecker The new context checker.
159             */
160            public void setContextChecker(ContextChecker contextChecker) {
161                    this.contextChecker = contextChecker;
162            }
163            
164            /**
165             * Returns the context checker of this text container.
166             * 
167             * @return The context checker.
168             */
169            public ContextChecker getContextChecker() {
170                    return contextChecker;
171            }
172            
173            /**
174             * Returns the position of the given text element within this text container or -1 if the
175             * text element is not contained by this text container. Note that the elements are checked for
176             * identity, not for equality.
177             * 
178             * @param textElement The text element.
179             * @return The index of the text element.
180             */
181            public int getIndexOf(TextElement textElement) {
182                    // indexOf(...) does not work, because it uses the equals-method, but we need to check for 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 (contextChecker == 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 contextChecker.getTextInContext(te, preceding, following);
207                    }
208            }
209    
210    }