    001    package org.maltparser.core.propagation;
    002
    003    import java.util.SortedSet;
    004    import java.util.TreeSet;
    005    import java.util.regex.Pattern;
    006
    007    import org.maltparser.core.exception.MaltChainedException;
    008    import org.maltparser.core.propagation.spec.PropagationSpec;
    009    import org.maltparser.core.symbol.SymbolTable;
    010    import org.maltparser.core.symbol.SymbolTableHandler;
    011    import org.maltparser.core.syntaxgraph.edge.Edge;
    012    import org.maltparser.core.syntaxgraph.node.DependencyNode;
    013
    014    /**
    015     * A propagation object propagate a column value from one node to a column in another node based on the propagation specification.
    016     *
    017     * @author Johan Hall
    018     *
    019     */
    020    public class Propagation {
    021            /**
    022             *
    023             */
    024            private SymbolTable fromTable;
    025            private SymbolTable toTable;
    026            private SymbolTable deprelTable;
    027            private SortedSet<String> forSet;
    028            private SortedSet<String> overSet;
    029
    030            private Pattern symbolSeparator;
    031
    032            /**
    033             * Creates a propagation object based on the propagation specification
    034             *
    035             * @param spec a propagation specification
    036             * @param symbolTables a symbol table
    037             * @throws MaltChainedException
    038             */
    039            public Propagation(PropagationSpec spec, SymbolTableHandler symbolTables) throws MaltChainedException {
    040                    fromTable = symbolTables.getSymbolTable(spec.getFrom());
    041                    if (fromTable == null) {
    042                            throw new PropagationException("The symbol table '"+spec.getFrom()+" does not exists.");
    043                    }
    044                    toTable = symbolTables.getSymbolTable(spec.getTo());
    045                    if (toTable == null) {
    046                            toTable = symbolTables.addSymbolTable(spec.getTo(), fromTable);
    047                    }
    048
    049                    forSet = new TreeSet<String>();
    050                    if (spec.getFor() != null && spec.getFor().length() > 0) {
    051                            String[] items = spec.getFor().split("\\|");
    052
    053                            for (String item : items) {
    054                                    forSet.add(item);
    055                            }
    056                    }
    057
    058                    overSet = new TreeSet<String>();
    059                    if (spec.getOver() != null && spec.getOver().length() > 0) {
    060                            String[] items = spec.getOver().split("\\|");
    061
    062                            for (String item : items) {
    063                                    overSet.add(item);
    064                            }
    065                    }
    066
    067                    deprelTable = symbolTables.getSymbolTable("DEPREL");
    068                    symbolSeparator = Pattern.compile("\\|");
    069            }
    070
    071            /**
    072             * Propagate columns according to the propagation specification
    073             *
    074             * @param e an edge
    075             * @throws MaltChainedException
    076             */
    077            public void propagate(Edge e) throws MaltChainedException {
    078                    if (e != null && e.hasLabel(deprelTable) && !e.getSource().isRoot()) {
    079                            if (overSet.size() == 0 || overSet.contains(e.getLabelSymbol(deprelTable))) {
    080                                    DependencyNode to = (DependencyNode)e.getSource();
    081                                    DependencyNode from = (DependencyNode)e.getTarget();
    082                                    String fromSymbol = null;
    083                                    if (e.hasLabel(fromTable)) {
    084                                            fromSymbol = e.getLabelSymbol(fromTable);
    085                                    } else if (from.hasLabel(fromTable)) {
    086                                            fromSymbol = from.getLabelSymbol(fromTable);
    087                                    }
    088
    089                                    String propSymbol = null;
    090                                    if (to.hasLabel(toTable)) {
    091                                            propSymbol = union(fromSymbol, to.getLabelSymbol(toTable));
    092                                    } else {
    093                                            if (forSet.size() == 0 || forSet.contains(fromSymbol)) {
    094                                                    propSymbol = fromSymbol;
    095                                            }
    096                                    }
    097                                    if (propSymbol != null) {
    098                                            to.addLabel(toTable, propSymbol);
    099                                    }
    100                            }
    101                    }
    102            }
    103
    104            private String union(String fromSymbol, String toSymbol) {
    105                    SortedSet<String> symbolSet = new TreeSet<String>();
    106
    107                    if (fromSymbol != null && fromSymbol.length() != 0) {
    108                            String[] fromSymbols = symbolSeparator.split(fromSymbol);
    109                            for (int i = 0; i < fromSymbols.length; i++) {
    110                                    if (forSet.size() == 0 || forSet.contains(fromSymbols[i])) {
    111                                            symbolSet.add(fromSymbols[i]);
    112                                    }
    113                            }
    114                    }
    115                    if (toSymbol != null && toSymbol.length() != 0) {
    116                            String[] toSymbols = symbolSeparator.split(toSymbol);
    117                            for (int i = 0; i < toSymbols.length; i++) {
    118                                    symbolSet.add(toSymbols[i]);
    119                            }
    120                    }
    121
    122                    if (symbolSet.size() > 0) {
    123                            StringBuilder sb = new StringBuilder();
    124                            for (String symbol : symbolSet) {
    125                                    sb.append(symbol);
    126                                    sb.append('|');
    127                            }
    128                            sb.setLength(sb.length()-1);
    129                            return sb.toString();
    130                    }
    131
    132
    133                    return "";
    134            }
    135            @Override
    136            public String toString() {
    137                    return "Propagation [forSet=" + forSet + ", fromTable=" + fromTable
    138                                    + ", overSet=" + overSet + ", toTable=" + toTable + "]";
    139            }
    140    }