001: // RuleParserException.java
002: // $Id: RuleNode.java,v 1.3 2000/08/16 21:38:05 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1998.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.www.protocol.http.proxy;
007:
008: import java.util.Hashtable;
009:
010: /**
011: * A RuleNode instance keeps track of one token within the lfh of a rule.
012: * This data structure is usually known as a <em>hash-trie</em>, check
013: * one of the Knuth books for more infos.
014: */
015: public class RuleNode {
016: /**
017: * The token this node applies to.
018: */
019: String token = null;
020: /**
021: * It's optionally associated rule.
022: */
023: Rule rule = null;
024: /**
025: * A hashtable to keep track of children rules.
026: */
027: Hashtable children = null;
028:
029: void setRule(Rule rule) {
030: this .rule = rule;
031: }
032:
033: public Rule getRule() {
034: return rule;
035: }
036:
037: public Hashtable getChildren() {
038: return children;
039: }
040:
041: /**
042: * Add a children rule node to this rule node.
043: * @param token The child token.
044: * @param rule The rule to map to this token.
045: * @return The newly created RuleNode instance.
046: */
047:
048: synchronized RuleNode addChild(String tok, Rule rule) {
049: RuleNode node = new RuleNode(tok, rule);
050: if (children == null)
051: children = new Hashtable(5);
052: children.put(tok, node);
053: return node;
054: }
055:
056: /**
057: * Add a children rule node to this node.
058: * This method does the same as above, except that it doesn't map
059: * the created node to a rule.
060: * @param tok The token this node applies to.
061: * @return The newly createed RuleNode instance.
062: */
063:
064: synchronized RuleNode addChild(String tok) {
065: RuleNode node = new RuleNode(tok);
066: if (children == null)
067: children = new Hashtable(5);
068: children.put(tok, node);
069: return node;
070: }
071:
072: /**
073: * Lookup a rule.
074: * Given a fully qualified host name, parse it into its components, and
075: * starting from this rule node, lookup for a matching rule.
076: * <p>The most precise rule is always returned.
077: * @return The best matching rule, as a Rule instance, or <strong>
078: * null</strong> if no matching rule was found.
079: */
080:
081: public Rule lookupRule(String host) {
082: // Parse the host into it's components:
083: String parts[] = new String[32];
084: int hostlen = host.length();
085: int phost = 0;
086: int npart = 0;
087: boolean isip = true;
088: for (int i = 0; i < hostlen; i++) {
089: if (host.charAt(i) == '.') {
090: if (npart + 1 >= parts.length) {
091: // This is unlikely to happen, but anyway:
092: String newparts[] = new String[parts.length << 1];
093: System.arraycopy(parts, 0, newparts, 0,
094: parts.length);
095: parts = newparts;
096: }
097: parts[npart++] = host.substring(phost, i);
098: phost = ++i;
099: } else {
100: if (isip)
101: isip = (host.charAt(i) >= '0')
102: && (host.charAt(i) <= '9');
103: }
104: }
105: parts[npart++] = host.substring(phost);
106:
107: RuleNode node = this ;
108: Rule ret = rule;
109: if (isip)
110: for (int i = 0; i <= npart; i++) {
111: node = node.lookup(parts[i]);
112: if (node != null) {
113: ret = (node.rule != null) ? node.rule : rule;
114: } else {
115: return ret;
116: }
117: }
118: else
119: for (int i = npart; --i >= 0;) {
120: node = node.lookup(parts[i]);
121: if (node != null) {
122: ret = (node.rule != null) ? node.rule : ret;
123: } else {
124: return ret;
125: }
126: }
127: return ret;
128: }
129:
130: /**
131: * Lookup a children rule node.
132: * @param tok The token for the child that is to be looked up.
133: * @return A RuleNode instance, if found, <strong>null</strong>
134: * otherwise.
135: */
136:
137: public RuleNode lookup(String tok) {
138: return ((children != null) ? (RuleNode) children.get(tok)
139: : null);
140: }
141:
142: RuleNode(String token, Rule rule) {
143: this .token = token.toLowerCase();
144: this .rule = rule;
145: }
146:
147: RuleNode(String token) {
148: this (token, null);
149: }
150:
151: RuleNode() {
152: this ("**ROOT**", null);
153: }
154: }
|