1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.mime4j.field.address;
21
22 import org.apache.james.mime4j.codec.DecoderUtil;
23 import org.apache.james.mime4j.field.address.parser.ASTaddr_spec;
24 import org.apache.james.mime4j.field.address.parser.ASTaddress;
25 import org.apache.james.mime4j.field.address.parser.ASTaddress_list;
26 import org.apache.james.mime4j.field.address.parser.ASTangle_addr;
27 import org.apache.james.mime4j.field.address.parser.ASTdomain;
28 import org.apache.james.mime4j.field.address.parser.ASTgroup_body;
29 import org.apache.james.mime4j.field.address.parser.ASTlocal_part;
30 import org.apache.james.mime4j.field.address.parser.ASTmailbox;
31 import org.apache.james.mime4j.field.address.parser.ASTname_addr;
32 import org.apache.james.mime4j.field.address.parser.ASTphrase;
33 import org.apache.james.mime4j.field.address.parser.ASTroute;
34 import org.apache.james.mime4j.field.address.parser.Node;
35 import org.apache.james.mime4j.field.address.parser.SimpleNode;
36 import org.apache.james.mime4j.field.address.parser.Token;
37
38 import java.util.ArrayList;
39 import java.util.Iterator;
40 import java.util.List;
41
42
43
44
45
46 class Builder {
47
48 private static Builder singleton = new Builder();
49
50 public static Builder getInstance() {
51 return singleton;
52 }
53
54 public AddressList buildAddressList(ASTaddress_list node) {
55 List<Address> list = new ArrayList<Address>();
56 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
57 ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
58 Address address = buildAddress(childNode);
59 list.add(address);
60 }
61 return new AddressList(list, true);
62 }
63
64 public Address buildAddress(ASTaddress node) {
65 ChildNodeIterator it = new ChildNodeIterator(node);
66 Node n = it.next();
67 if (n instanceof ASTaddr_spec) {
68 return buildAddrSpec((ASTaddr_spec) n);
69 } else if (n instanceof ASTangle_addr) {
70 return buildAngleAddr((ASTangle_addr) n);
71 } else if (n instanceof ASTphrase) {
72 String name = buildString((ASTphrase) n, false);
73 Node n2 = it.next();
74 if (n2 instanceof ASTgroup_body) {
75 return new Group(name, buildGroupBody((ASTgroup_body) n2));
76 } else if (n2 instanceof ASTangle_addr) {
77 name = DecoderUtil.decodeEncodedWords(name);
78 return new Mailbox(name, buildAngleAddr((ASTangle_addr) n2));
79 } else {
80 throw new IllegalStateException();
81 }
82 } else {
83 throw new IllegalStateException();
84 }
85 }
86
87 private MailboxList buildGroupBody(ASTgroup_body node) {
88 List<Mailbox> results = new ArrayList<Mailbox>();
89 ChildNodeIterator it = new ChildNodeIterator(node);
90 while (it.hasNext()) {
91 Node n = it.next();
92 if (n instanceof ASTmailbox)
93 results.add(buildMailbox((ASTmailbox) n));
94 else
95 throw new IllegalStateException();
96 }
97 return new MailboxList(results, true);
98 }
99
100 public Mailbox buildMailbox(ASTmailbox node) {
101 ChildNodeIterator it = new ChildNodeIterator(node);
102 Node n = it.next();
103 if (n instanceof ASTaddr_spec) {
104 return buildAddrSpec((ASTaddr_spec) n);
105 } else if (n instanceof ASTangle_addr) {
106 return buildAngleAddr((ASTangle_addr) n);
107 } else if (n instanceof ASTname_addr) {
108 return buildNameAddr((ASTname_addr) n);
109 } else {
110 throw new IllegalStateException();
111 }
112 }
113
114 private Mailbox buildNameAddr(ASTname_addr node) {
115 ChildNodeIterator it = new ChildNodeIterator(node);
116 Node n = it.next();
117 String name;
118 if (n instanceof ASTphrase) {
119 name = buildString((ASTphrase) n, false);
120 } else {
121 throw new IllegalStateException();
122 }
123
124 n = it.next();
125 if (n instanceof ASTangle_addr) {
126 name = DecoderUtil.decodeEncodedWords(name);
127 return new Mailbox(name, buildAngleAddr((ASTangle_addr) n));
128 } else {
129 throw new IllegalStateException();
130 }
131 }
132
133 private Mailbox buildAngleAddr(ASTangle_addr node) {
134 ChildNodeIterator it = new ChildNodeIterator(node);
135 DomainList route = null;
136 Node n = it.next();
137 if (n instanceof ASTroute) {
138 route = buildRoute((ASTroute) n);
139 n = it.next();
140 } else if (n instanceof ASTaddr_spec) {
141
142 }
143 else
144 throw new IllegalStateException();
145
146 if (n instanceof ASTaddr_spec)
147 return buildAddrSpec(route, (ASTaddr_spec) n);
148 else
149 throw new IllegalStateException();
150 }
151
152 private DomainList buildRoute(ASTroute node) {
153 List<String> results = new ArrayList<String>(node.jjtGetNumChildren());
154 ChildNodeIterator it = new ChildNodeIterator(node);
155 while (it.hasNext()) {
156 Node n = it.next();
157 if (n instanceof ASTdomain)
158 results.add(buildString((ASTdomain) n, true));
159 else
160 throw new IllegalStateException();
161 }
162 return new DomainList(results, true);
163 }
164
165 private Mailbox buildAddrSpec(ASTaddr_spec node) {
166 return buildAddrSpec(null, node);
167 }
168
169 private Mailbox buildAddrSpec(DomainList route, ASTaddr_spec node) {
170 ChildNodeIterator it = new ChildNodeIterator(node);
171 String localPart = buildString((ASTlocal_part) it.next(), true);
172 String domain = buildString((ASTdomain) it.next(), true);
173 return new Mailbox(route, localPart, domain);
174 }
175
176 private String buildString(SimpleNode node, boolean stripSpaces) {
177 Token head = node.firstToken;
178 Token tail = node.lastToken;
179 StringBuilder out = new StringBuilder();
180
181 while (head != tail) {
182 out.append(head.image);
183 head = head.next;
184 if (!stripSpaces)
185 addSpecials(out, head.specialToken);
186 }
187 out.append(tail.image);
188
189 return out.toString();
190 }
191
192 private void addSpecials(StringBuilder out, Token specialToken) {
193 if (specialToken != null) {
194 addSpecials(out, specialToken.specialToken);
195 out.append(specialToken.image);
196 }
197 }
198
199 private static class ChildNodeIterator implements Iterator<Node> {
200
201 private SimpleNode simpleNode;
202 private int index;
203 private int len;
204
205 public ChildNodeIterator(SimpleNode simpleNode) {
206 this.simpleNode = simpleNode;
207 this.len = simpleNode.jjtGetNumChildren();
208 this.index = 0;
209 }
210
211 public void remove() {
212 throw new UnsupportedOperationException();
213 }
214
215 public boolean hasNext() {
216 return index < len;
217 }
218
219 public Node next() {
220 return simpleNode.jjtGetChild(index++);
221 }
222
223 }
224 }