source: contrib/MailArchiver/sources/vendor/mime4j/custom/dom/src/main/java/org/apache/james/mime4j/field/address/Builder.java @ 6785

Revision 6785, 8.4 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;
34
35/**
36 * Transforms the JJTree-generated abstract syntax tree into a graph of
37 * org.apache.james.mime4j.dom.address objects.
38 */
39class Builder {
40
41    private static Builder singleton = new Builder();
42
43    public static Builder getInstance() {
44        return singleton;
45    }
46
47    public AddressList buildAddressList(ASTaddress_list node, DecodeMonitor monitor) throws ParseException {
48        List<Address> list = new ArrayList<Address>();
49        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
50            ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
51            Address address = buildAddress(childNode, monitor);
52            list.add(address);
53        }
54        return new AddressList(list, true);
55    }
56
57    public Address buildAddress(ASTaddress node, DecodeMonitor monitor) throws ParseException {
58        ChildNodeIterator it = new ChildNodeIterator(node);
59        Node n = it.next();
60        if (n instanceof ASTaddr_spec) {
61            return buildAddrSpec((ASTaddr_spec) n);
62        } else if (n instanceof ASTangle_addr) {
63            return buildAngleAddr((ASTangle_addr) n);
64        } else if (n instanceof ASTphrase) {
65            String name = buildString((ASTphrase) n, false);
66            Node n2 = it.next();
67            if (n2 instanceof ASTgroup_body) {
68                return new Group(name, buildGroupBody((ASTgroup_body) n2, monitor));
69            } else if (n2 instanceof ASTangle_addr) {
70                try {
71                    name = DecoderUtil.decodeEncodedWords(name, monitor);
72                } catch (IllegalArgumentException e) {
73                    throw new ParseException(e.getMessage());
74                }
75                Mailbox mb = buildAngleAddr((ASTangle_addr) n2);
76                return new Mailbox(name, mb.getRoute(), mb.getLocalPart(),
77                        mb.getDomain());
78            } else {
79                throw new ParseException();
80            }
81        } else {
82            throw new ParseException();
83        }
84    }
85
86    private MailboxList buildGroupBody(ASTgroup_body node, DecodeMonitor monitor) throws ParseException {
87        List<Mailbox> results = new ArrayList<Mailbox>();
88        ChildNodeIterator it = new ChildNodeIterator(node);
89        while (it.hasNext()) {
90            Node n = it.next();
91            if (n instanceof ASTmailbox)
92                results.add(buildMailbox((ASTmailbox) n, monitor));
93            else
94                throw new ParseException();
95        }
96        return new MailboxList(results, true);
97    }
98
99    public Mailbox buildMailbox(ASTmailbox node, DecodeMonitor monitor) throws ParseException {
100        ChildNodeIterator it = new ChildNodeIterator(node);
101        Node n = it.next();
102        if (n instanceof ASTaddr_spec) {
103            return buildAddrSpec((ASTaddr_spec) n);
104        } else if (n instanceof ASTangle_addr) {
105            return buildAngleAddr((ASTangle_addr) n);
106        } else if (n instanceof ASTname_addr) {
107            return buildNameAddr((ASTname_addr) n, monitor);
108        } else {
109            throw new ParseException();
110        }
111    }
112
113    private Mailbox buildNameAddr(ASTname_addr node, DecodeMonitor monitor) throws ParseException {
114        ChildNodeIterator it = new ChildNodeIterator(node);
115        Node n = it.next();
116        String name;
117        if (n instanceof ASTphrase) {
118            name = buildString((ASTphrase) n, false);
119        } else {
120            throw new ParseException();
121        }
122
123        n = it.next();
124        if (n instanceof ASTangle_addr) {
125            try {
126                name = DecoderUtil.decodeEncodedWords(name, monitor);
127            } catch (IllegalArgumentException e) {
128                throw new ParseException(e.getMessage());
129            }
130            Mailbox mb = buildAngleAddr((ASTangle_addr) n);
131            return new Mailbox(name, mb.getRoute(), mb.getLocalPart(),
132                    mb.getDomain());
133        } else {
134            throw new ParseException();
135        }
136    }
137
138    private Mailbox buildAngleAddr(ASTangle_addr node) throws ParseException {
139        ChildNodeIterator it = new ChildNodeIterator(node);
140        DomainList route = null;
141        Node n = it.next();
142        if (n instanceof ASTroute) {
143            route = buildRoute((ASTroute) n);
144            n = it.next();
145        } else if (n instanceof ASTaddr_spec) {
146            // do nothing
147        }
148        else
149            throw new ParseException();
150
151        if (n instanceof ASTaddr_spec)
152            return buildAddrSpec(route, (ASTaddr_spec) n);
153        else
154            throw new ParseException();
155    }
156
157    private DomainList buildRoute(ASTroute node) throws ParseException {
158        List<String> results = new ArrayList<String>(node.jjtGetNumChildren());
159        ChildNodeIterator it = new ChildNodeIterator(node);
160        while (it.hasNext()) {
161            Node n = it.next();
162            if (n instanceof ASTdomain)
163                results.add(buildString((ASTdomain) n, true));
164            else
165                throw new ParseException();
166        }
167        return new DomainList(results, true);
168    }
169
170    private Mailbox buildAddrSpec(ASTaddr_spec node) {
171        return buildAddrSpec(null, node);
172    }
173
174    private Mailbox buildAddrSpec(DomainList route, ASTaddr_spec node) {
175        ChildNodeIterator it = new ChildNodeIterator(node);
176        String localPart = buildString((ASTlocal_part) it.next(), true);
177        String domain = buildString((ASTdomain) it.next(), true);
178        return new Mailbox(route, localPart, domain);
179    }
180
181    private String buildString(SimpleNode node, boolean stripSpaces) {
182        Token head = node.firstToken;
183        Token tail = node.lastToken;
184        StringBuilder out = new StringBuilder();
185
186        while (head != tail) {
187            out.append(head.image);
188            head = head.next;
189            if (!stripSpaces)
190                addSpecials(out, head.specialToken);
191        }
192        out.append(tail.image);
193
194        return out.toString();
195    }
196
197    private void addSpecials(StringBuilder out, Token specialToken) {
198        if (specialToken != null) {
199            addSpecials(out, specialToken.specialToken);
200            out.append(specialToken.image);
201        }
202    }
203
204    private static class ChildNodeIterator implements Iterator<Node> {
205
206        private SimpleNode simpleNode;
207        private int index;
208        private int len;
209
210        public ChildNodeIterator(SimpleNode simpleNode) {
211            this.simpleNode = simpleNode;
212            this.len = simpleNode.jjtGetNumChildren();
213            this.index = 0;
214        }
215
216        public void remove() {
217            throw new UnsupportedOperationException();
218        }
219
220        public boolean hasNext() {
221            return index < len;
222        }
223
224        public Node next() {
225            return simpleNode.jjtGetChild(index++);
226        }
227
228    }
229}
Note: See TracBrowser for help on using the repository browser.