package org.greenstone.server; import java.io.Serializable; import java.util.HashMap; public class GazetteerTrieNode implements Serializable { private static final long serialVersionUID = 8121262849365540679L; protected boolean _nameEnd = false; protected GazetteerTrieNode[] _children = new GazetteerTrieNode[26]; protected HashMap _unicodeCharacters = null; /** * Basic constructor for a non-unicode trie node * @param nameEnd defines whether the new node represents the end of a place name */ protected GazetteerTrieNode(boolean nameEnd) { for(int i = 0; i < 26; i++) { _children[i] = null; } _nameEnd = nameEnd; } /** * Add a child to the current node * @param c is the character used to decide where to add the child node * @param nameEnd is whether or not this character represents the end of a place name * @return true if a child was added and false if one already existed */ protected boolean addChild(char c, boolean nameEnd) { //If the characters is an ASCII letter int index; if(c >= 'A' && c <= 'Z') { index = c - 65; } else if(c >= 'a' && c <= 'z') { index = c - 97; } //If the character is not an ASCII letter else { //If the node does not currently have a unicode character map then make one if(_unicodeCharacters == null) { _unicodeCharacters = new HashMap(); _unicodeCharacters.put(c, new GazetteerTrieNode(nameEnd)); return true; } //Add the unicode character to the map only if it either does not exist already or signifies the end of a place name GazetteerTrieNode value; if((value = _unicodeCharacters.get(c)) != null) { if(value.isNameEnd()) { return false; } else { value.setNameEnd(nameEnd); } } else { _unicodeCharacters.put(c, new GazetteerTrieNode(nameEnd)); } return true; } //Add the ascii character if it either does not already exist or it signifies the end of a place name if(_children[index] != null) { if(_children[index].isNameEnd() || nameEnd == false) { return false; } else { _children[index].setNameEnd(true); return true; } } else { _children[index] = new GazetteerTrieNode(nameEnd); return true; } } /** * @return whether or not this node represents the end of a place name */ protected boolean isNameEnd() { return _nameEnd; } /** * Set whether or not this node represents the end of a place name * @param nameEnd is the value to set it to */ protected void setNameEnd(boolean nameEnd) { _nameEnd = nameEnd; } /** * Returns the child at the given index * @param index is the index of the child to return * @return the child at the given index */ protected GazetteerTrieNode getChild(char c) { int index = -1; if(c >= 'A' && c <= 'Z') { index = c - 65; } else if(c >= 'a' && c <= 'z') { index = c - 97; } if(index == -1) { if(_unicodeCharacters == null) { return null; } return _unicodeCharacters.get(c); } return _children[index]; } public void output() { if(_unicodeCharacters != null && _unicodeCharacters.size() >= 10) { System.out.println(_unicodeCharacters.size()); } for(GazetteerTrieNode g : _children) { if(g != null) { g.output(); } } } }