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