source: contrib/MailArchiver/sources/vendor/mime4j/apache-mime4j-0.7-SNAPSHOT-20110327.010440-17/dom/src/main/java/org/apache/james/mime4j/field/address/Builder.java @ 6785

Revision 6785, 9.2 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2946 - Liberado codigo do MailArchiver?. Documentação na subpasta DOCS.

Line 
1/****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one   *
3 * or more contributor license agreements.  See the NOTICE file *
4 * distributed with this work for additional information        *
5 * regarding copyright ownership.  The ASF licenses this file   *
6 * to you under the Apache License, Version 2.0 (the            *
7 * "License"); you may not use this file except in compliance   *
8 * with the License.  You may obtain a copy of the License at   *
9 *                                                              *
10 *   http://www.apache.org/licenses/LICENSE-2.0                 *
11 *                                                              *
12 * Unless required by applicable law or agreed to in writing,   *
13 * software distributed under the License is distributed on an  *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15 * KIND, either express or implied.  See the License for the    *
16 * specific language governing permissions and limitations      *
17 * under the License.                                           *
18 ****************************************************************/
19
20package org.apache.james.mime4j.field.address;
21
22import java.util.ArrayList;
23import java.util.Iterator;
24import java.util.List;
25
26import org.apache.james.mime4j.codec.DecodeMonitor;
27import org.apache.james.mime4j.codec.DecoderUtil;
28import org.apache.james.mime4j.dom.address.Address;
29import org.apache.james.mime4j.dom.address.AddressList;
30import org.apache.james.mime4j.dom.address.DomainList;
31import org.apache.james.mime4j.dom.address.Group;
32import org.apache.james.mime4j.dom.address.Mailbox;
33import org.apache.james.mime4j.dom.address.MailboxList;
34import org.apache.james.mime4j.field.address.ASTaddr_spec;
35import org.apache.james.mime4j.field.address.ASTaddress;
36import org.apache.james.mime4j.field.address.ASTaddress_list;
37import org.apache.james.mime4j.field.address.ASTangle_addr;
38import org.apache.james.mime4j.field.address.ASTdomain;
39import org.apache.james.mime4j.field.address.ASTgroup_body;
40import org.apache.james.mime4j.field.address.ASTlocal_part;
41import org.apache.james.mime4j.field.address.ASTmailbox;
42import org.apache.james.mime4j.field.address.ASTname_addr;
43import org.apache.james.mime4j.field.address.ASTphrase;
44import org.apache.james.mime4j.field.address.ASTroute;
45import org.apache.james.mime4j.field.address.Node;
46import org.apache.james.mime4j.field.address.ParseException;
47import org.apache.james.mime4j.field.address.SimpleNode;
48import org.apache.james.mime4j.field.address.Token;
49
50/**
51 * Transforms the JJTree-generated abstract syntax tree into a graph of
52 * org.apache.james.mime4j.dom.address objects.
53 */
54class Builder {
55
56    private static Builder singleton = new Builder();
57
58    public static Builder getInstance() {
59        return singleton;
60    }
61
62    public AddressList buildAddressList(ASTaddress_list node, DecodeMonitor monitor) throws ParseException {
63        List<Address> list = new ArrayList<Address>();
64        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
65            ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
66            Address address = buildAddress(childNode, monitor);
67            list.add(address);
68        }
69        return new AddressList(list, true);
70    }
71
72    public Address buildAddress(ASTaddress node, DecodeMonitor monitor) throws ParseException {
73        ChildNodeIterator it = new ChildNodeIterator(node);
74        Node n = it.next();
75        if (n instanceof ASTaddr_spec) {
76            return buildAddrSpec((ASTaddr_spec) n);
77        } else if (n instanceof ASTangle_addr) {
78            return buildAngleAddr((ASTangle_addr) n);
79        } else if (n instanceof ASTphrase) {
80            String name = buildString((ASTphrase) n, false);
81            Node n2 = it.next();
82            if (n2 instanceof ASTgroup_body) {
83                return new Group(name, buildGroupBody((ASTgroup_body) n2, monitor));
84            } else if (n2 instanceof ASTangle_addr) {
85                try {
86                    name = DecoderUtil.decodeEncodedWords(name, monitor);
87                } catch (IllegalArgumentException e) {
88                    throw new ParseException(e.getMessage());
89                }
90                Mailbox mb = buildAngleAddr((ASTangle_addr) n2);
91                return new Mailbox(name, mb.getRoute(), mb.getLocalPart(),
92                        mb.getDomain());
93            } else {
94                throw new ParseException();
95            }
96        } else {
97            throw new ParseException();
98        }
99    }
100
101    private MailboxList buildGroupBody(ASTgroup_body node, DecodeMonitor monitor) throws ParseException {
102        List<Mailbox> results = new ArrayList<Mailbox>();
103        ChildNodeIterator it = new ChildNodeIterator(node);
104        while (it.hasNext()) {
105            Node n = it.next();
106            if (n instanceof ASTmailbox)
107                results.add(buildMailbox((ASTmailbox) n, monitor));
108            else
109                throw new ParseException();
110        }
111        return new MailboxList(results, true);
112    }
113
114    public Mailbox buildMailbox(ASTmailbox node, DecodeMonitor monitor) throws ParseException {
115        ChildNodeIterator it = new ChildNodeIterator(node);
116        Node n = it.next();
117        if (n instanceof ASTaddr_spec) {
118            return buildAddrSpec((ASTaddr_spec) n);
119        } else if (n instanceof ASTangle_addr) {
120            return buildAngleAddr((ASTangle_addr) n);
121        } else if (n instanceof ASTname_addr) {
122            return buildNameAddr((ASTname_addr) n, monitor);
123        } else {
124            throw new ParseException();
125        }
126    }
127
128    private Mailbox buildNameAddr(ASTname_addr node, DecodeMonitor monitor) throws ParseException {
129        ChildNodeIterator it = new ChildNodeIterator(node);
130        Node n = it.next();
131        String name;
132        if (n instanceof ASTphrase) {
133            name = buildString((ASTphrase) n, false);
134        } else {
135            throw new ParseException();
136        }
137
138        n = it.next();
139        if (n instanceof ASTangle_addr) {
140            try {
141                name = DecoderUtil.decodeEncodedWords(name, monitor);
142            } catch (IllegalArgumentException e) {
143                throw new ParseException(e.getMessage());
144            }
145            Mailbox mb = buildAngleAddr((ASTangle_addr) n);
146            return new Mailbox(name, mb.getRoute(), mb.getLocalPart(),
147                    mb.getDomain());
148        } else {
149            throw new ParseException();
150        }
151    }
152
153    private Mailbox buildAngleAddr(ASTangle_addr node) throws ParseException {
154        ChildNodeIterator it = new ChildNodeIterator(node);
155        DomainList route = null;
156        Node n = it.next();
157        if (n instanceof ASTroute) {
158            route = buildRoute((ASTroute) n);
159            n = it.next();
160        } else if (n instanceof ASTaddr_spec) {
161            // do nothing
162        }
163        else
164            throw new ParseException();
165
166        if (n instanceof ASTaddr_spec)
167            return buildAddrSpec(route, (ASTaddr_spec) n);
168        else
169            throw new ParseException();
170    }
171
172    private DomainList buildRoute(ASTroute node) throws ParseException {
173        List<String> results = new ArrayList<String>(node.jjtGetNumChildren());
174        ChildNodeIterator it = new ChildNodeIterator(node);
175        while (it.hasNext()) {
176            Node n = it.next();
177            if (n instanceof ASTdomain)
178                results.add(buildString((ASTdomain) n, true));
179            else
180                throw new ParseException();
181        }
182        return new DomainList(results, true);
183    }
184
185    private Mailbox buildAddrSpec(ASTaddr_spec node) {
186        return buildAddrSpec(null, node);
187    }
188
189    private Mailbox buildAddrSpec(DomainList route, ASTaddr_spec node) {
190        ChildNodeIterator it = new ChildNodeIterator(node);
191        String localPart = buildString((ASTlocal_part) it.next(), true);
192        String domain = buildString((ASTdomain) it.next(), true);
193        return new Mailbox(route, localPart, domain);
194    }
195
196    private String buildString(SimpleNode node, boolean stripSpaces) {
197        Token head = node.firstToken;
198        Token tail = node.lastToken;
199        StringBuilder out = new StringBuilder();
200
201        while (head != tail) {
202            out.append(head.image);
203            head = head.next;
204            if (!stripSpaces)
205                addSpecials(out, head.specialToken);
206        }
207        out.append(tail.image);
208
209        return out.toString();
210    }
211
212    private void addSpecials(StringBuilder out, Token specialToken) {
213        if (specialToken != null) {
214            addSpecials(out, specialToken.specialToken);
215            out.append(specialToken.image);
216        }
217    }
218
219    private static class ChildNodeIterator implements Iterator<Node> {
220
221        private SimpleNode simpleNode;
222        private int index;
223        private int len;
224
225        public ChildNodeIterator(SimpleNode simpleNode) {
226            this.simpleNode = simpleNode;
227            this.len = simpleNode.jjtGetNumChildren();
228            this.index = 0;
229        }
230
231        public void remove() {
232            throw new UnsupportedOperationException();
233        }
234
235        public boolean hasNext() {
236            return index < len;
237        }
238
239        public Node next() {
240            return simpleNode.jjtGetChild(index++);
241        }
242
243    }
244}
Note: See TracBrowser for help on using the repository browser.