001 package org.maltparser.core.syntaxgraph;
002
003 import java.util.NoSuchElementException;
004 import java.util.Observable;
005 import java.util.SortedMap;
006 import java.util.SortedSet;
007 import java.util.TreeMap;
008 import java.util.TreeSet;
009
010 import org.maltparser.core.exception.MaltChainedException;
011 import org.maltparser.core.pool.ObjectPoolList;
012 import org.maltparser.core.symbol.SymbolTableHandler;
013
014 import org.maltparser.core.syntaxgraph.node.Token;
015 import org.maltparser.core.syntaxgraph.node.TokenNode;
016 /**
017 *
018 *
019 * @author Johan Hall
020 */
021 public 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 = null;
061 if (!terminalNodes.containsKey(index)) {
062 if (index > 0){
063 node = terminalPool.checkOut();
064 node.setIndex(index);
065 node.setBelongsToGraph(this);
066
067 if (index > 1) {
068 Token prev = terminalNodes.get(index-1);
069 if (prev == null) {
070 try {
071 prev = terminalNodes.get(terminalNodes.headMap(index).lastKey());
072 } catch (NoSuchElementException e) {
073
074 }
075 }
076 if (prev != null) {
077 prev.setSuccessor(node);
078 node.setPredecessor(prev);
079 }
080
081 if (terminalNodes.lastKey() > index) {
082 Token succ = terminalNodes.get(index+1);
083 if (succ == null) {
084 try {
085 succ = terminalNodes.get(terminalNodes.tailMap(index).firstKey());
086 } catch (NoSuchElementException e) {
087
088 }
089 }
090 if (succ != null) {
091 succ.setPredecessor(node);
092 node.setSuccessor(succ);
093 }
094 }
095 }
096 }
097 terminalNodes.put(index,node);
098 numberOfComponents++;
099 } else {
100 node = terminalNodes.get(index);
101 }
102 return node;
103 }
104
105 public SortedSet<Integer> getTokenIndices() {
106 return new TreeSet<Integer>(terminalNodes.keySet());
107 }
108
109 public int getHighestTokenIndex() {
110 try {
111 return terminalNodes.lastKey();
112 } catch (NoSuchElementException e) {
113 return 0;
114 }
115 }
116
117 public TokenNode getTokenNode(int index) {
118 if (index > 0) {
119 return terminalNodes.get(index);
120 }
121 return null;
122 }
123
124
125 public int getSentenceID() {
126 return sentenceID;
127 }
128
129 public void setSentenceID(int sentenceID) {
130 this.sentenceID = sentenceID;
131 }
132
133 public void clear() throws MaltChainedException {
134 terminalPool.checkInAll();
135 terminalNodes.clear();
136 sentenceID = 0;
137 super.clear();
138 }
139
140 public void update(Observable o, Object str) { }
141
142 public String toString() {
143 final StringBuilder sb = new StringBuilder();
144 for (int index : terminalNodes.keySet()) {
145 sb.append(terminalNodes.get(index).toString().trim());
146 sb.append('\n');
147 }
148 sb.append("\n");
149 return sb.toString();
150 }
151 }