001package org.maltparser.core.syntaxgraph;
002
003import java.util.ArrayList;
004import java.util.NoSuchElementException;
005import java.util.Observable;
006import java.util.SortedMap;
007import java.util.SortedSet;
008import java.util.TreeMap;
009import java.util.TreeSet;
010
011import org.maltparser.core.exception.MaltChainedException;
012import org.maltparser.core.helper.HashMap;
013import org.maltparser.core.pool.ObjectPoolList;
014import org.maltparser.core.symbol.SymbolTableHandler;
015import org.maltparser.core.syntaxgraph.node.Token;
016import org.maltparser.core.syntaxgraph.node.TokenNode;
017/**
018*
019*
020* @author Johan Hall
021*/
022public class Sentence extends SyntaxGraph implements TokenStructure {
023        protected final ObjectPoolList<Token> terminalPool;
024        protected final SortedMap<Integer,Token> terminalNodes;
025        protected final HashMap<Integer, ArrayList<String>> comments;
026        protected int sentenceID;
027        
028        public Sentence(SymbolTableHandler symbolTables) throws MaltChainedException {
029                super(symbolTables);
030                terminalNodes = new TreeMap<Integer,Token>();
031                terminalPool = new ObjectPoolList<Token>() {
032                        protected Token create() throws MaltChainedException { return new Token(); }
033                        public void resetObject(Token o) throws MaltChainedException { o.clear(); }
034                };
035                comments = new HashMap<Integer, ArrayList<String>>();
036        }
037
038        public TokenNode addTokenNode(int index) throws MaltChainedException {
039                if (index > 0) {
040                        return getOrAddTerminalNode(index);
041                }
042                return null;
043        }
044        
045        public TokenNode addTokenNode() throws MaltChainedException {
046                int index = getHighestTokenIndex();
047                if (index > 0) {
048                        return getOrAddTerminalNode(index+1);
049                }
050                return getOrAddTerminalNode(1);
051        }
052        
053        public void addComment(String comment, int at_index) {
054                ArrayList<String> commentList = comments.get(at_index);
055                if (commentList == null) {
056                        commentList = new ArrayList<String>();
057                        comments.put(at_index, commentList);
058                }
059                commentList.add(comment);
060        }
061        
062        public ArrayList<String> getComment(int at_index) {
063                return comments.get(at_index);
064        }
065        
066        public boolean hasComments() {
067                return comments.size() > 0;
068        }
069        
070        public int nTokenNode() {
071                return terminalNodes.size();
072        }
073        
074        public boolean hasTokens() {
075                return !terminalNodes.isEmpty();
076        }
077        
078        
079        protected Token getOrAddTerminalNode(int index) throws MaltChainedException {
080                Token node = terminalNodes.get(index);
081                if (node == null) {
082//              if (!terminalNodes.containsKey(index)) {
083                        if (index > 0){
084                                node = terminalPool.checkOut();
085                                node.setIndex(index);
086                                node.setBelongsToGraph(this); 
087                                
088                                if (index > 1) {
089                                        Token prev = terminalNodes.get(index-1);
090                                        if (prev == null) {
091                                                try {
092                                                        prev = terminalNodes.get(terminalNodes.headMap(index).lastKey());
093                                                } catch (NoSuchElementException e) {
094                                                        
095                                                }
096                                        }
097                                        if (prev != null) {
098                                                prev.setSuccessor(node);
099                                                node.setPredecessor(prev);
100                                        }
101                                        
102                                        if (terminalNodes.lastKey() > index) {
103                                                Token succ = terminalNodes.get(index+1);
104                                                if (succ == null) {
105                                                        try {
106                                                                succ = terminalNodes.get(terminalNodes.tailMap(index).firstKey());
107                                                        } catch (NoSuchElementException e) {
108                                                                
109                                                        }
110                                                }
111                                                if (succ != null) {
112                                                        succ.setPredecessor(node);
113                                                        node.setSuccessor(succ);
114                                                }
115                                        }
116                                }
117                        }
118                        terminalNodes.put(index,node);
119                        numberOfComponents++;
120                } 
121//              else {
122//                      node = terminalNodes.get(index);
123//              }
124                return node;
125        }
126        
127        public SortedSet<Integer> getTokenIndices() {
128                return new TreeSet<Integer>(terminalNodes.keySet());
129        }
130        
131        public int getHighestTokenIndex() {
132                try {
133                        return terminalNodes.lastKey();
134                } catch (NoSuchElementException e) {
135                        return 0;
136                }
137        }
138        
139        public TokenNode getTokenNode(int index) {
140                if (index > 0) {
141                        return terminalNodes.get(index);
142                }
143                return null;
144        }
145        
146        
147        public int getSentenceID() {
148                return sentenceID;
149        }
150
151        public void setSentenceID(int sentenceID) {
152                this.sentenceID = sentenceID;
153        }
154
155        public void clear() throws MaltChainedException {
156                terminalPool.checkInAll();
157                terminalNodes.clear();
158                comments.clear();
159                sentenceID = 0;
160                super.clear();
161        }
162        
163        public void update(Observable  o, Object str) { }
164        
165        public String toString() {
166                final StringBuilder sb = new StringBuilder();
167                for (int index : terminalNodes.keySet()) {
168                        sb.append(terminalNodes.get(index).toString().trim());
169                        sb.append('\n');
170                }
171                sb.append("\n");
172                return sb.toString();
173        }
174}