source: contrib/MailArchiver/sources/vendor/mime4j/apache-mime4j-0.7-SNAPSHOT-20110327.010440-17/examples/src/main/java/org/apache/james/mime4j/samples/tree/MessageTree.java @ 6785

Revision 6785, 13.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.samples.tree;
21
22import java.awt.Dimension;
23import java.awt.GridLayout;
24import java.io.FileInputStream;
25import java.io.FileNotFoundException;
26import java.io.IOException;
27import java.io.InputStream;
28import java.io.Reader;
29import java.util.Date;
30import java.util.Map;
31
32import javax.swing.JFrame;
33import javax.swing.JPanel;
34import javax.swing.JScrollPane;
35import javax.swing.JSplitPane;
36import javax.swing.JTextArea;
37import javax.swing.JTree;
38import javax.swing.event.TreeSelectionEvent;
39import javax.swing.event.TreeSelectionListener;
40import javax.swing.tree.DefaultMutableTreeNode;
41import javax.swing.tree.TreeSelectionModel;
42
43import org.apache.james.mime4j.dom.BinaryBody;
44import org.apache.james.mime4j.dom.Body;
45import org.apache.james.mime4j.dom.Entity;
46import org.apache.james.mime4j.dom.Header;
47import org.apache.james.mime4j.dom.Message;
48import org.apache.james.mime4j.dom.Multipart;
49import org.apache.james.mime4j.dom.TextBody;
50import org.apache.james.mime4j.dom.address.Mailbox;
51import org.apache.james.mime4j.dom.address.MailboxList;
52import org.apache.james.mime4j.dom.field.AddressListField;
53import org.apache.james.mime4j.dom.field.ContentTypeField;
54import org.apache.james.mime4j.dom.field.DateTimeField;
55import org.apache.james.mime4j.dom.field.Field;
56import org.apache.james.mime4j.dom.field.UnstructuredField;
57import org.apache.james.mime4j.field.address.AddressFormatter;
58import org.apache.james.mime4j.message.BodyPart;
59import org.apache.james.mime4j.message.MessageImpl;
60import org.apache.james.mime4j.message.MimeBuilder;
61
62/**
63 * Displays a parsed Message in a window. The window will be divided into
64 * two panels. The left panel displays the Message tree. Clicking on a
65 * node in the tree shows information on that node in the right panel.
66 *
67 * Some of this code have been copied from the Java tutorial's JTree section.
68 */
69public class MessageTree extends JPanel implements TreeSelectionListener {
70    private static final long serialVersionUID = 1L;
71
72    private JPanel contentPane;
73    private JTextArea textView;
74    private JTree tree;
75
76    /**
77     * Wraps an Object and associates it with a text. All message parts
78     * (headers, bodies, multiparts, body parts) will be wrapped in
79     * ObjectWrapper instances before they are added to the JTree instance.
80     */
81    public static class ObjectWrapper {
82        private String text = "";
83        private Object object = null;
84
85        public ObjectWrapper(String text, Object object) {
86            this.text = text;
87            this.object = object;
88        }
89
90        @Override
91        public String toString() {
92            return text;
93        }
94
95        public Object getObject() {
96            return object;
97        }
98    }
99
100    /**
101     * Creates a new <code>MessageTree</code> instance displaying the
102     * specified <code>Message</code>.
103     *
104     * @param message the message to display.
105     */
106    public MessageTree(Message message) {
107        super(new GridLayout(1,0));
108
109        DefaultMutableTreeNode root = createNode(message);
110
111        tree = new JTree(root);
112        tree.getSelectionModel().setSelectionMode(
113                TreeSelectionModel.SINGLE_TREE_SELECTION);
114
115        tree.addTreeSelectionListener(this);
116
117        JScrollPane treeView = new JScrollPane(tree);
118
119        contentPane = new JPanel(new GridLayout(1,0));
120        JScrollPane contentView = new JScrollPane(contentPane);
121
122        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
123        splitPane.setLeftComponent(treeView);
124        splitPane.setRightComponent(contentView);
125
126        Dimension minimumSize = new Dimension(100, 50);
127        contentView.setMinimumSize(minimumSize);
128        treeView.setMinimumSize(minimumSize);
129        splitPane.setDividerLocation(250);
130        splitPane.setPreferredSize(new Dimension(750, 500));
131
132        add(splitPane);
133
134        textView = new JTextArea();
135        textView.setEditable(false);
136        textView.setLineWrap(true);
137        contentPane.add(textView);
138    }
139
140    /**
141     * Create a node given a Multipart body.
142     * Add the Preamble, all Body parts and the Epilogue to the node.
143     *
144     * @param multipart the Multipart.
145     * @return the root node of the tree.
146     */
147    private DefaultMutableTreeNode createNode(Header header) {
148        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
149                new ObjectWrapper("Header", header));
150
151        for (Field field : header.getFields()) {
152            String name = field.getName();
153
154            node.add(new DefaultMutableTreeNode(new ObjectWrapper(name, field)));
155        }
156
157        return node;
158    }
159
160    /**
161     * Create a node given a Multipart body.
162     * Add the Preamble, all Body parts and the Epilogue to the node.
163     *
164     * @param multipart the Multipart.
165     * @return the root node of the tree.
166     */
167    private DefaultMutableTreeNode createNode(Multipart multipart) {
168        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
169                new ObjectWrapper("Multipart", multipart));
170
171        node.add(new DefaultMutableTreeNode(
172                       new ObjectWrapper("Preamble", multipart.getPreamble())));
173        for (Entity part : multipart.getBodyParts()) {
174            node.add(createNode(part));
175        }
176        node.add(new DefaultMutableTreeNode(
177                       new ObjectWrapper("Epilogue", multipart.getEpilogue())));
178
179        return node;
180    }
181
182    /**
183     * Creates the tree nodes given a MIME entity (either a Message or
184     * a BodyPart).
185     *
186     * @param entity the entity.
187     * @return the root node of the tree displaying the specified entity and
188     *         its children.
189     */
190    private DefaultMutableTreeNode createNode(Entity entity) {
191
192        /*
193         * Create the root node for the entity. It's either a
194         * Message or a Body part.
195         */
196        String type = "Message";
197        if (entity instanceof BodyPart) {
198            type = "Body part";
199        }
200        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
201                                            new ObjectWrapper(type, entity));
202
203        /*
204         * Add the node encapsulating the entity Header.
205         */
206        node.add(createNode(entity.getHeader()));
207
208        Body body = entity.getBody();
209
210        if (body instanceof Multipart) {
211            /*
212             * The body of the entity is a Multipart.
213             */
214
215            node.add(createNode((Multipart) body));
216        } else if (body instanceof MessageImpl) {
217            /*
218             * The body is another Message.
219             */
220
221            node.add(createNode((MessageImpl) body));
222
223        } else {
224            /*
225             * Discrete Body (either of type TextBody or BinaryBody).
226             */
227            type = "Text body";
228            if (body instanceof BinaryBody) {
229                type = "Binary body";
230            }
231
232            type += " (" + entity.getMimeType() + ")";
233            node.add(new DefaultMutableTreeNode(new ObjectWrapper(type, body)));
234
235        }
236
237        return node;
238    }
239
240    /**
241     * Called whenever the selection changes in the JTree instance showing
242     * the Message nodes.
243     *
244     * @param e the event.
245     */
246    public void valueChanged(TreeSelectionEvent e) {
247        DefaultMutableTreeNode node = (DefaultMutableTreeNode)
248                tree.getLastSelectedPathComponent();
249
250        textView.setText("");
251
252        if (node == null) {
253            return;
254        }
255
256        Object o = ((ObjectWrapper) node.getUserObject()).getObject();
257
258        if (node.isLeaf()) {
259
260            if (o instanceof TextBody){
261                /*
262                 * A text body. Display its contents.
263                 */
264                TextBody body = (TextBody) o;
265                StringBuilder sb = new StringBuilder();
266                try {
267                    Reader r = body.getReader();
268                    int c;
269                    while ((c = r.read()) != -1) {
270                        sb.append((char) c);
271                    }
272                } catch (IOException ex) {
273                    ex.printStackTrace();
274                }
275                textView.setText(sb.toString());
276
277            } else if (o instanceof BinaryBody){
278                /*
279                 * A binary body. Display its MIME type and length in bytes.
280                 */
281                BinaryBody body = (BinaryBody) o;
282                int size = 0;
283                try {
284                    InputStream is = body.getInputStream();
285                    while ((is.read()) != -1) {
286                        size++;
287                    }
288                } catch (IOException ex) {
289                    ex.printStackTrace();
290                }
291                textView.setText("Binary body\n"
292                               + "MIME type: "
293                                   + body.getParent().getMimeType() + "\n"
294                               + "Size of decoded data: " + size + " bytes");
295
296            } else if (o instanceof ContentTypeField) {
297                /*
298                 * Content-Type field.
299                 */
300                ContentTypeField field = (ContentTypeField) o;
301                StringBuilder sb = new StringBuilder();
302                sb.append("MIME type: " + field.getMimeType() + "\n");
303                Map<String, String> params = field.getParameters();
304                for (String name : params.keySet()) {
305                    sb.append(name + " = " + params.get(name) + "\n");
306                }
307                textView.setText(sb.toString());
308
309            } else if (o instanceof AddressListField) {
310                /*
311                 * An address field (From, To, Cc, etc)
312                 */
313                AddressListField field = (AddressListField) o;
314                MailboxList list = field.getAddressList().flatten();
315                StringBuilder sb = new StringBuilder();
316                for (int i = 0; i < list.size(); i++) {
317                    Mailbox mb = list.get(i);
318                    sb.append(AddressFormatter.DEFAULT.format(mb, false) + "\n");
319                }
320                textView.setText(sb.toString());
321
322            } else if (o instanceof DateTimeField) {
323                Date date = ((DateTimeField) o).getDate();
324                textView.setText(date.toString());
325            } else if (o instanceof UnstructuredField){
326                textView.setText(((UnstructuredField) o).getValue());
327            } else if (o instanceof Field){
328                textView.setText(((Field) o).getBody());
329            } else {
330                /*
331                 * The Object should be a Header or a String containing a
332                 * Preamble or Epilogue.
333                 */
334                textView.setText(o.toString());
335            }
336
337        }
338    }
339
340    /**
341     * Creates and displays the gui.
342     *
343     * @param message the Message to display in the tree.
344     */
345    private static void createAndShowGUI(Message message) {
346        /*
347         * Create and set up the window.
348         */
349        JFrame frame = new JFrame("MessageTree");
350        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
351
352        /*
353         * Create and set up the content pane.
354         */
355        MessageTree newContentPane = new MessageTree(message);
356        newContentPane.setOpaque(true);
357        frame.setContentPane(newContentPane);
358
359        /*
360         * Display the window.
361         */
362        frame.pack();
363        frame.setVisible(true);
364    }
365
366    public static void main(String[] args) {
367        try {
368
369            final Message message = MimeBuilder.DEFAULT.parse(new FileInputStream(args[0]));
370
371            javax.swing.SwingUtilities.invokeLater(new Runnable() {
372                public void run() {
373                    createAndShowGUI(message);
374                }
375            });
376
377        } catch (ArrayIndexOutOfBoundsException e) {
378            System.err.println("Wrong number of arguments.");
379            System.err.println("Usage: org.mime4j.samples.tree.MessageTree"
380                             + " path/to/message");
381        } catch (FileNotFoundException e) {
382            System.err.println("The file '" + args[0] + "' could not be found.");
383        } catch (IOException e) {
384            System.err.println("The file '" + args[0] + "' could not be read.");
385        }
386    }
387
388}
Note: See TracBrowser for help on using the repository browser.