Android Open Source - sdk-hyphenation Tree Node






From Project

Back to project page sdk-hyphenation.

License

The source code is released under:

GNU Lesser General Public License

If you think the Android project sdk-hyphenation listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.silpa.hyphenation.text;
//from www. j ava 2  s.c o  m
import org.silpa.hyphenation.util.List;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Logger;

/**
 * Tree structure for representing hyphenation rules in a type safe manner.
 */
public class TreeNode {
    private static final Logger log = Logger.getLogger(TreeNode.class.getCanonicalName());
    private final String segment;
    private final int[] hyphenation;
    private final boolean blank;
    private final Map<Character, TreeNode> children = new Hashtable<Character, TreeNode>();

    private final static Comparator<TreeNode> CHILD_ORDER_COMPARATOR = new Comparator<TreeNode>() {
        public int compare(TreeNode o1, TreeNode o2) {
            if (o1.getLastCharacter() > o2.getLastCharacter()) {
                return 1;
            } else if (o1.getLastCharacter() < o2.getLastCharacter()) {
                return -1;
            } else {
                return 0;
            }
        }
    };

    /**
     * Create a root node to create all other nodes inside.
     *
     * @return TreeNode object
     */
    public static TreeNode createRoot() {
        return new TreeNode("");
    }

    /**
     * Create a new node from a string pattern
     *
     * @param pattern string
     * @return Treenode object
     */
    public static TreeNode createFromPattern(String pattern) {
        char[] patternChars = pattern.toCharArray();

        int characterCount = 0;
        boolean largeHyphenation = false;
        char[] segmentChars = new char[patternChars.length];
        int[] hyphenations = new int[patternChars.length + 1];

        for (char c : patternChars) {
            if (Character.isDigit(c)) {
                hyphenations[characterCount] = hyphenations[characterCount] * 10 + Integer.parseInt("" + c);

                if (hyphenations[characterCount] > 9) {
                    largeHyphenation = true;
                }
            } else {
                segmentChars[characterCount++] = c;
            }
        }


        if (largeHyphenation) {
            final String msg = "Pattern \' " + pattern + " \' contained a hyphernation larger than 9.";
            log.warning(msg);
        }

        return new TreeNode(
                String.copyValueOf(segmentChars, 0, characterCount),
                copyOfRange(hyphenations, 0, characterCount + 1)
        );
    }

    /**
     * Arrays.copyOfRange() was implemented in Java 6, and we still need Java 5 as the minimum requirement.
     */
    private static int[] copyOfRange(int[] srcArray, int offset, int length) {
        int[] destArray = new int[length];
        for (int i = offset; i < length; i++) {
            destArray[i] = srcArray[offset + i];
        }
        return destArray;
    }

    /**
     * Constructor
     * Create a node with no hyphenation information (a blank node).
     *
     * @param segment string
     */
    public TreeNode(String segment) {
        this.segment = segment;
        this.hyphenation = new int[segment.length() + 1];
        this.blank = true;
    }

    /**
     * Create a node with hyphenation information.
     *
     * @param segment         string
     * @param hyphenationData int array with hyphenation data
     */
    public TreeNode(String segment, int[] hyphenationData) {
        if (segment.length() + 1 != hyphenationData.length) {
            throw new IllegalArgumentException(
                    "Illegal lenght of hyphenation array for \'" + segment + "\'. " +
                            "It should be " + (segment.length() + 1) + " but was " + hyphenationData.length + "."
            );
        }

        this.segment = segment;
        this.hyphenation = hyphenationData;
        this.blank = false;
    }

    /**
     * Add a child rule to this node. The child node must match a longer, more
     * specialized, segment than the segment of the node it is added to.
     * Grandchildren will recursively added to children of this node.
     *
     * @param segment     The string of text that this rule matches against
     * @param hyphenation They hypenation information for this match
     */
    public void createChild(String segment, int[] hyphenation) {
        if (!segment.startsWith(this.segment)) {
            throw new IllegalArgumentException("Can not add child \'" + segment
                    + "\' to parent \'" + this.segment + "\'");
        }

        TreeNode newNode = new TreeNode(segment, hyphenation);

        if (segment.length() == this.segment.length() + 1) {
            final char keyChar = segment.charAt(segment.length() - 1);

            if (children.containsKey(keyChar)) {
                final TreeNode existingNode = children.get(keyChar);
                if (!existingNode.isBlank()) {
                    final String msg =
                            "Duplicate pattern. Pattern \'" + existingNode.getPattern() + "\' will be replaced by \'" + newNode.getPattern() + "\'.";
                    log.warning(msg);

                }
                newNode.copyChildren(existingNode);
            }

            children.put(keyChar, newNode);
        } else {
            final char keyCharacter = segment.charAt(this.segment.length());
            if (!hasChild(keyCharacter)) {
                addBlankChild(keyCharacter);
            }
            getChild(keyCharacter).createChild(segment, hyphenation);
        }
    }

    /**
     * Copy all children from another node.
     *
     * @param source TreeNode source
     */
    private void copyChildren(TreeNode source) {
        for (char c : source.children.keySet()) {
            this.children.put(c, source.getChild(c));
        }
    }

    /**
     * Add place holder node required by tree structure.
     *
     * @param nodeCharacter character
     */
    private void addBlankChild(char nodeCharacter) {
        children.put(nodeCharacter, new TreeNode(this.segment + nodeCharacter));
    }

    /**
     * Parse pattern and add the resulting segment and hyphernation to the tree.
     *
     * @param pattern string
     */
    public void createChildFromPattern(String pattern) {
        TreeNode tmpNode = TreeNode.createFromPattern(pattern);
        this.createChild(tmpNode.getSegment(), tmpNode.getHyphenation());
    }


    public String getSegment() {
        return segment;
    }

    public char getLastCharacter() {
        return segment.charAt(segment.length() - 1);
    }

    public int[] getHyphenation() {
        return hyphenation;
    }

    /**
     * To get pattern
     *
     * @return string
     */
    public String getPattern() {
        StringBuffer pattern = new StringBuffer();

        for (int i = 0; i < segment.length(); i++) {

            final int prefixHyphenatoion = hyphenation[i];
            if (prefixHyphenatoion > 0) {
                pattern.append(prefixHyphenatoion);
            }
            pattern.append(segment.charAt(i));
        }
        final int lastHyphenation = hyphenation[segment.length()];
        if (lastHyphenation > 0) {
            pattern.append(lastHyphenation);
        }

        return pattern.toString();
    }

    public boolean hasChild(char c) {
        return children.containsKey(c);
    }

    /**
     * To get child
     *
     * @param c character
     * @return TreeNode
     */
    public TreeNode getChild(char c) {
        return children.get(c);
    }

    /**
     * Is this the root node onto which all other nodes should be added?
     *
     * @return true/false
     */
    public boolean isRoot() {
        return this.segment == "";
    }

    /**
     * Node is only a place holder required by the tree structure.
     *
     * @return true/false
     */
    public boolean isBlank() {
        return this.blank;
    }

    /**
     * Create texhyphj original (lisp like) List structure from node tree for consumption by Hypernator
     *
     * @return List
     */
    public List toList() {
        List list = new List();

        if (!isRoot()) {
            list.snoc(Character.valueOf(getLastCharacter()));
            list.snoc(getHyphenation());
        }

        //The List structures from the original implementation where in alphabetical order.
        final ArrayList<TreeNode> childList = new ArrayList<TreeNode>(children.values());
        Collections.sort(childList, CHILD_ORDER_COMPARATOR);
        for (TreeNode c : childList) {
            list.snoc(c.toList());
        }

        return list;
    }
}




Java Source Code List

org.silpa.hyphenation.text.ByteScanner.java
org.silpa.hyphenation.text.Hyphenator.java
org.silpa.hyphenation.text.RuleDefinition.java
org.silpa.hyphenation.text.TreeNode.java
org.silpa.hyphenation.text.Utf8TexParser.java
org.silpa.hyphenation.util.Applicator.java
org.silpa.hyphenation.util.ErrorHandler.java
org.silpa.hyphenation.util.Hashtable.java
org.silpa.hyphenation.util.List.java
org.silpa.hyphenation.util.LoggingErrorHandler.java