1 package com.thaiopensource.validate.nrl; 2 3 import com.thaiopensource.xml.util.Naming; 4 5 import java.util.Vector ; 6 7 class Path { 8 private final boolean root; 9 private final Vector names; 10 11 Path(boolean root, Vector names) { 12 this.root = root; 13 this.names = names; 14 } 15 16 boolean isRoot() { 17 return root; 18 } 19 20 Vector getNames() { 21 return names; 22 } 23 24 public String toString() { 25 StringBuffer buf = new StringBuffer (); 26 if (root) 27 buf.append('/'); 28 for (int i = 0, len = names.size(); i < len; i++) { 29 if (i != 0) 30 buf.append('/'); 31 buf.append((String )names.elementAt(i)); 32 } 33 return buf.toString(); 34 } 35 36 static class ParseException extends Exception { 37 private final String messageKey; 38 39 ParseException(String messageKey) { 40 super(messageKey); 41 this.messageKey = messageKey; 42 } 43 44 public String getMessageKey() { 45 return messageKey; 46 } 47 } 48 49 private static final int START = 0; 50 private static final int IN_NAME = 1; 51 private static final int AFTER_NAME = 2; 52 private static final int AFTER_SLASH = 3; 53 54 static Vector parse(String str) throws ParseException { 55 int state = START; 56 int nameStartIndex = -1; 57 Vector paths = new Vector (); 58 Vector names = new Vector (); 59 boolean root = false; 60 for (int i = 0, len = str.length(); i < len; i++) { 61 char c = str.charAt(i); 62 switch (c) { 63 case ' ': 64 case '\r': 65 case '\n': 66 case '\t': 67 if (state == IN_NAME) { 68 names.addElement(makeName(str, nameStartIndex, i)); 69 state = AFTER_NAME; 70 } 71 break; 72 case '/': 73 switch (state) { 74 case IN_NAME: 75 names.addElement(makeName(str, nameStartIndex, i)); 76 break; 77 case START: 78 root = true; 79 break; 80 case AFTER_SLASH: 81 throw new ParseException("unexpected_slash"); 82 } 83 state = AFTER_SLASH; 84 break; 85 case '|': 86 switch (state) { 87 case START: 88 throw new ParseException("empty_path"); 89 case AFTER_NAME: 90 break; 91 case AFTER_SLASH: 92 throw new ParseException("expected_name"); 93 case IN_NAME: 94 names.addElement(makeName(str, nameStartIndex, i)); 95 break; 96 } 97 paths.addElement(new Path(root, names)); 98 root = false; 99 names = new Vector (); 100 state = START; 101 break; 102 default: 103 switch (state) { 104 case AFTER_NAME: 105 throw new ParseException("expected_slash"); 106 case AFTER_SLASH: 107 case START: 108 nameStartIndex = i; 109 state = IN_NAME; 110 break; 111 case IN_NAME: 112 break; 113 } 114 break; 115 } 116 } 117 switch (state) { 118 case START: 119 throw new ParseException("empty_path"); 120 case AFTER_NAME: 121 break; 122 case AFTER_SLASH: 123 throw new ParseException("expected_name"); 124 case IN_NAME: 125 names.addElement(makeName(str, nameStartIndex, str.length())); 126 break; 127 } 128 paths.addElement(new Path(root, names)); 129 return paths; 130 } 131 132 private static String makeName(String str, int start, int end) throws ParseException { 133 String name = str.substring(start, end); 134 if (!Naming.isNcname(name)) 135 throw new ParseException("invalid_name"); 136 return name; 137 } 138 139 static public void main(String [] args) throws ParseException { 140 Vector paths = parse(args[0]); 141 for (int i = 0; i < paths.size(); i++) { 142 if (i != 0) 143 System.out.println("---"); 144 Path path = (Path)paths.elementAt(i); 145 if (path.isRoot()) 146 System.out.println("/"); 147 for (int j = 0; j < path.getNames().size(); j++) 148 System.out.println(path.getNames().elementAt(j)); 149 } 150 } 151 } 152 | Popular Tags |