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 }