001package org.maltparser.core.syntaxgraph.headrules;
002
003import java.util.ArrayList;
004
005import org.apache.log4j.Logger;
006import org.maltparser.core.exception.MaltChainedException;
007import org.maltparser.core.io.dataformat.DataFormatInstance;
008import org.maltparser.core.symbol.SymbolTable;
009import org.maltparser.core.symbol.SymbolTableHandler;
010import org.maltparser.core.syntaxgraph.node.NonTerminalNode;
011import org.maltparser.core.syntaxgraph.node.PhraseStructureNode;
012/**
013*
014*
015* @author Johan Hall
016*/
017public class HeadRule extends ArrayList<PrioList> {
018        public static final long serialVersionUID = 8045568022124826323L;
019        protected HeadRules headRules;
020        protected SymbolTable table;
021        protected int symbolCode;
022        protected Direction defaultDirection;
023        
024        public HeadRule(HeadRules headRules, String ruleSpec) throws MaltChainedException {
025                setHeadRules(headRules);
026                init(ruleSpec);
027        }
028        
029        public void init(String ruleSpec) throws MaltChainedException {
030                String spec = ruleSpec.trim();
031                String[] items = spec.split("\t");
032                if (items.length != 3) {
033                        throw new HeadRuleException("The specification of the head rule is not correct '"+ruleSpec+"'. ");
034                }
035                
036                int index = items[0].indexOf(':');
037                if (index != -1) {
038                        SymbolTable t = headRules.getSymbolTableHandler().getSymbolTable(items[0].substring(0, index));
039                        if (t == null) {
040                                throw new HeadRuleException("The specification of the head rule is not correct '"+ruleSpec+"'. ");
041                        }
042                        setTable(t);
043                        setSymbolCode(table.addSymbol(items[0].substring(index+1)));
044                } else {
045                        throw new HeadRuleException("The specification of the head rule is not correct '"+ruleSpec+"'. ");
046                }
047                if (items[1].charAt(0) == 'r') {
048                        defaultDirection = Direction.RIGHT;     
049                } else if (items[1].charAt(0) == 'l') {
050                        defaultDirection = Direction.LEFT;
051                } else {
052                        throw new HeadRuleException("Could not determine the default direction of the head rule '"+ruleSpec+"'. ");
053                }
054                if (items[2].length() > 1) {
055                        if (items[2].indexOf(';') == -1) {
056                                add(new PrioList(this, items[2]));
057                        } else {
058                                String[] lists = items[2].split(";");
059                                for (int i = 0; i < lists.length; i++) {
060                                        add(new PrioList(this, lists[i]));
061                                }
062                        }
063                }
064        }
065
066        public PhraseStructureNode getHeadChild(NonTerminalNode nt) throws MaltChainedException {
067                PhraseStructureNode headChild = null;
068                for (int i = 0; i < size(); i++) {
069                        headChild = get(i).getHeadChild(nt);
070                        if (headChild != null) {
071                                break;
072                        }
073                }
074                return headChild;
075        }
076        
077        public SymbolTable getTable() {
078                return table;
079        }
080        
081        public void setTable(SymbolTable table) {
082                this.table = table;
083        }
084        
085        public int getSymbolCode() {
086                return symbolCode;
087        }
088        
089        public void setSymbolCode(int symbolCode) {
090                this.symbolCode = symbolCode;
091        }
092        
093        public String getSymbolString() throws MaltChainedException {
094                return table.getSymbolCodeToString(symbolCode);
095        }
096        
097        public Direction getDefaultDirection() {
098                return defaultDirection;
099        }
100        
101        public void setDefaultDirection(Direction direction) {
102                this.defaultDirection = direction;
103        }
104        
105        public Logger getLogger() {
106                return headRules.getLogger();
107        }
108        
109    public DataFormatInstance getDataFormatInstance() {
110                return headRules.getDataFormatInstance();
111        }
112    
113        public SymbolTableHandler getSymbolTableHandler() {
114                return headRules.getSymbolTableHandler();
115        }
116        
117        public void setHeadRules(HeadRules headRules) {
118                this.headRules = headRules;
119        }
120        
121        public String toString() {
122                final StringBuilder sb = new StringBuilder();
123                sb.append(table.getName());
124                sb.append(':');
125                try {
126                        sb.append(getSymbolString());
127                } catch (MaltChainedException e) {
128                        if (getLogger().isDebugEnabled()) {
129                                getLogger().debug("",e);
130                        } else {
131                                getLogger().error(e.getMessageChain());
132                        }
133                }
134                sb.append('\t');
135                if (defaultDirection == Direction.LEFT) {
136                        sb.append('l');
137                } else if (defaultDirection == Direction.RIGHT) {
138                        sb.append('r');
139                }
140                sb.append('\t');
141                if (size() == 0) {
142                        sb.append('*');
143                } else {
144                        for (int i = 0; i < size(); i++) {
145                                sb.append(get(i));
146                                if (i < size()-1) {
147                                        sb.append(';');
148                                }
149                        }
150                }
151                return sb.toString();
152        }
153}