1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.seasar.cubby.routing.impl;
18
19 import static org.seasar.cubby.internal.util.LogMessages.format;
20
21 import org.seasar.cubby.routing.PathTemplateException;
22 import org.seasar.cubby.routing.PathTemplateParser;
23
24
25
26
27
28
29 public class PathTemplateParserImpl implements PathTemplateParser {
30
31
32 private static final char OPEN_PLACE_HOLDER = '{';
33
34
35 private static final char CLOSE_PLACE_HOLDER = '}';
36
37
38 private static final char PLACE_HOLDER_SEPARATOR = ',';
39
40
41 private static final char REGEXP_ESCAPE = '\\';
42
43
44
45
46
47
48 private enum State {
49 NORMAL, PARAM_NAME, PARAM_REGEX, PARAM_REGEX_ESCAPE;
50 }
51
52
53
54
55 public String parse(final String template, final Handler handler) {
56 final StringBuilder pathRegex = new StringBuilder(100);
57 final StringBuilder paramName = new StringBuilder(10);
58 final StringBuilder paramRegex = new StringBuilder(10);
59
60 State state = State.NORMAL;
61 int braceDepth = 0;
62
63 for (int i = 0; i < template.length(); i++) {
64 final char c = template.charAt(i);
65 switch (state) {
66 case NORMAL: {
67 if (c == OPEN_PLACE_HOLDER) {
68 state = State.PARAM_NAME;
69 } else {
70 pathRegex.append(c);
71 }
72 break;
73 }
74 case PARAM_NAME: {
75 if (c == CLOSE_PLACE_HOLDER) {
76 if (paramName.length() == 0) {
77 throw new PathTemplateException(format("ECUB0108",
78 template, i));
79 }
80 final String replacement = handler.handle(paramName
81 .toString(), DEFAULT_URI_PARAMETER_REGEX);
82 pathRegex.append(replacement);
83
84 paramName.setLength(0);
85 state = State.NORMAL;
86 } else if (c == PLACE_HOLDER_SEPARATOR) {
87 state = State.PARAM_REGEX;
88 } else {
89 paramName.append(c);
90 }
91 break;
92 }
93 case PARAM_REGEX: {
94 if (c == REGEXP_ESCAPE) {
95 paramRegex.append(c);
96 state = State.PARAM_REGEX_ESCAPE;
97 } else if (c == CLOSE_PLACE_HOLDER && braceDepth == 0) {
98 if (paramName.length() == 0) {
99 throw new PathTemplateException(format("ECUB0108",
100 template, i));
101 }
102 if (paramRegex.length() == 0) {
103 throw new PathTemplateException(format("ECUB0109",
104 template, i));
105 }
106 final String replacement = handler.handle(paramName
107 .toString(), paramRegex.toString());
108 pathRegex.append(replacement);
109
110 paramName.setLength(0);
111 paramRegex.setLength(0);
112 braceDepth = 0;
113 state = State.NORMAL;
114 } else {
115 if (c == OPEN_PLACE_HOLDER) {
116 braceDepth++;
117 } else if (c == CLOSE_PLACE_HOLDER) {
118 braceDepth--;
119 }
120 paramRegex.append(c);
121 }
122 break;
123 }
124 case PARAM_REGEX_ESCAPE: {
125 paramRegex.append(c);
126 state = State.PARAM_REGEX;
127 break;
128 }
129 default:
130 throw new IllegalStateException();
131 }
132 }
133 if (state != State.NORMAL) {
134 throw new PathTemplateException(format("ECUB0107", template));
135 }
136 return pathRegex.toString();
137 }
138
139 }