move the only example to a new location (examples)

git-svn-id: https://svn.apache.org/repos/asf/james/mime4j/branches/maven2-port@438052 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/examples/src/java/org/mime4j/samples/tree/MessageTree.java b/examples/src/java/org/mime4j/samples/tree/MessageTree.java
new file mode 100644
index 0000000..7077795
--- /dev/null
+++ b/examples/src/java/org/mime4j/samples/tree/MessageTree.java
@@ -0,0 +1,371 @@
+package org.mime4j.samples.tree;
+
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+import javax.swing.JTree;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeSelectionModel;
+
+import org.mime4j.field.AddressListField;
+import org.mime4j.field.ContentTypeField;
+import org.mime4j.field.DateTimeField;
+import org.mime4j.field.Field;
+import org.mime4j.field.UnstructuredField;
+import org.mime4j.field.address.Mailbox;
+import org.mime4j.field.address.MailboxList;
+import org.mime4j.message.BinaryBody;
+import org.mime4j.message.Body;
+import org.mime4j.message.BodyPart;
+import org.mime4j.message.Entity;
+import org.mime4j.message.Header;
+import org.mime4j.message.Message;
+import org.mime4j.message.Multipart;
+import org.mime4j.message.TextBody;
+
+/**
+ * Displays a parsed Message in a window. The window will be divided into
+ * two panels. The left panel displays the Message tree. Clicking on a 
+ * node in the tree shows information on that node in the right panel.
+ *
+ * Some of this code have been copied from the Java tutorial's JTree section.
+ *
+ * @author Niklas Therning
+ * @version $Id$
+ */
+public class MessageTree extends JPanel implements TreeSelectionListener {
+    private JPanel contentPane;
+    private JTextArea textView;
+    private JTree tree;
+
+    /**
+     * Wraps an Object and associates it with a text. All message parts 
+     * (headers, bodies, multiparts, body parts) will be wrapped in
+     * ObjectWrapper instances before they are added to the JTree instance.
+     */
+    public static class ObjectWrapper {
+        private String text = "";
+        private Object object = null;
+        
+        public ObjectWrapper(String text, Object object) {
+            this.text = text;
+            this.object = object;
+        }
+        
+        public String toString() {
+            return text;
+        }
+        
+        public Object getObject() {
+            return object;
+        }
+    }
+    
+    /**
+     * Creates a new <code>MessageTree</code> instance displaying the 
+     * specified <code>Message</code>.
+     * 
+     * @param message the message to display.
+     */
+    public MessageTree(Message message) {
+        super(new GridLayout(1,0));
+
+        DefaultMutableTreeNode root = createNode(message);
+
+        tree = new JTree(root);
+        tree.getSelectionModel().setSelectionMode(
+                TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+        tree.addTreeSelectionListener(this);
+
+        JScrollPane treeView = new JScrollPane(tree);
+
+        contentPane = new JPanel(new GridLayout(1,0));
+        JScrollPane contentView = new JScrollPane(contentPane);
+
+        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+        splitPane.setLeftComponent(treeView);
+        splitPane.setRightComponent(contentView);
+
+        Dimension minimumSize = new Dimension(100, 50);
+        contentView.setMinimumSize(minimumSize);
+        treeView.setMinimumSize(minimumSize);
+        splitPane.setDividerLocation(250);
+        splitPane.setPreferredSize(new Dimension(750, 500));
+
+        add(splitPane);
+        
+        textView = new JTextArea();
+        textView.setEditable(false);
+        textView.setLineWrap(true);
+        contentPane.add(textView);
+    }
+    
+    /**
+     * Create a node given a Multipart body.
+     * Add the Preamble, all Body parts and the Epilogue to the node.
+     * 
+     * @param multipart the Multipart.
+     * @return the root node of the tree.
+     */
+    private DefaultMutableTreeNode createNode(Header header) {
+        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
+                new ObjectWrapper("Header", header));
+
+        for (Iterator it = header.getFields().iterator(); it.hasNext();) {
+            Field field = (Field) it.next();
+            String name = field.getName();
+            
+            node.add(new DefaultMutableTreeNode(new ObjectWrapper(name, field)));
+        }        
+
+        return node;
+    }
+    
+    /**
+     * Create a node given a Multipart body.
+     * Add the Preamble, all Body parts and the Epilogue to the node.
+     * 
+     * @param multipart the Multipart.
+     * @return the root node of the tree.
+     */
+    private DefaultMutableTreeNode createNode(Multipart multipart) {
+        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
+                new ObjectWrapper("Multipart", multipart));
+
+        node.add(new DefaultMutableTreeNode(
+                       new ObjectWrapper("Preamble", multipart.getPreamble())));
+        for (Iterator it = multipart.getBodyParts().iterator(); it.hasNext();) {
+            BodyPart part = (BodyPart) it.next();
+            node.add(createNode(part));
+        }
+        node.add(new DefaultMutableTreeNode(
+                       new ObjectWrapper("Epilogue", multipart.getEpilogue())));
+
+        return node;
+    }
+    
+    /**
+     * Creates the tree nodes given a MIME entity (either a Message or 
+     * a BodyPart).
+     * 
+     * @param entity the entity.
+     * @return the root node of the tree displaying the specified entity and 
+     *         its children.
+     */
+    private DefaultMutableTreeNode createNode(Entity entity) {
+        
+        /*
+         * Create the root node for the entity. It's either a
+         * Message or a Body part.
+         */
+        String type = "Message";
+        if (entity instanceof BodyPart) {
+            type = "Body part";
+        }
+        DefaultMutableTreeNode node = new DefaultMutableTreeNode(
+                                            new ObjectWrapper(type, entity));
+
+        /*
+         * Add the node encapsulating the entity Header.
+         */
+        node.add(createNode(entity.getHeader()));
+        
+        Body body = entity.getBody();
+        
+        if (body instanceof Multipart) {
+            /*
+             * The body of the entity is a Multipart.
+             */
+            
+            node.add(createNode((Multipart) body));
+        } else if (body instanceof Message) {
+            /*
+             * The body is another Message.
+             */
+            
+            node.add(createNode((Message) body));
+            
+        } else {
+            /*
+             * Discrete Body (either of type TextBody or BinaryBody).
+             */
+            type = "Text body";
+            if (body instanceof BinaryBody) {
+                type = "Binary body";
+            }
+            
+            type += " (" + entity.getMimeType() + ")";
+            node.add(new DefaultMutableTreeNode(new ObjectWrapper(type, body)));
+            
+        }
+        
+        return node;
+    }
+    
+    /**
+     * Called whenever the selection changes in the JTree instance showing
+     * the Message nodes.
+     * 
+     * @param e the event.
+     */
+    public void valueChanged(TreeSelectionEvent e) {
+        DefaultMutableTreeNode node = (DefaultMutableTreeNode)
+                tree.getLastSelectedPathComponent();
+
+        textView.setText("");
+        
+        if (node == null) {
+            return;
+        }
+        
+        Object o = ((ObjectWrapper) node.getUserObject()).getObject();
+
+        if (node.isLeaf()) {
+            
+            if (o instanceof TextBody){
+                /*
+                 * A text body. Display its contents.
+                 */
+                TextBody body = (TextBody) o;
+                StringBuffer sb = new StringBuffer();
+                try {
+                    Reader r = body.getReader();
+                    int c;
+                    while ((c = r.read()) != -1) {
+                        sb.append((char) c);
+                    }
+                } catch (IOException ex) {
+                    ex.printStackTrace();
+                }
+                textView.setText(sb.toString());
+                
+            } else if (o instanceof BinaryBody){
+                /*
+                 * A binary body. Display its MIME type and length in bytes.
+                 */
+                BinaryBody body = (BinaryBody) o;
+                int size = 0;
+                try {
+                    InputStream is = body.getInputStream();
+                    int b;
+                    while ((b = is.read()) != -1) {
+                        size++;
+                    }
+                } catch (IOException ex) {
+                    ex.printStackTrace();
+                }
+                textView.setText("Binary body\n"
+                               + "MIME type: " 
+                                   + body.getParent().getMimeType() + "\n" 
+                               + "Size of decoded data: " + size + " bytes");
+                
+            } else if (o instanceof ContentTypeField) {
+                /*
+                 * Content-Type field.
+                 */
+                ContentTypeField field = (ContentTypeField) o;
+                StringBuffer sb = new StringBuffer();
+                sb.append("MIME type: " + field.getMimeType() + "\n");
+                Map params = field.getParameters();
+                for (Iterator it = params.keySet().iterator(); it.hasNext();) {
+                    String name = (String) it.next();
+                    sb.append(name + " = " + params.get(name) + "\n");
+                }
+                textView.setText(sb.toString());
+                
+            } else if (o instanceof AddressListField) {
+                /*
+                 * An address field (From, To, Cc, etc)
+                 */
+                AddressListField field = (AddressListField) o;
+                MailboxList list = field.getAddressList().flatten();
+                StringBuffer sb = new StringBuffer();
+                for (int i = 0; i < list.size(); i++) {
+                    Mailbox mb = list.get(i);
+                    sb.append(mb.getAddressString() + "\n");
+                }
+                textView.setText(sb.toString());
+                
+            } else if (o instanceof DateTimeField) {
+                Date date = ((DateTimeField) o).getDate();
+                textView.setText(date.toString());                
+            } else if (o instanceof UnstructuredField){
+                textView.setText(((UnstructuredField) o).getValue());                
+            } else if (o instanceof Field){
+                textView.setText(((Field) o).getBody());                
+            } else {
+                /*
+                 * The Object should be a Header or a String containing a 
+                 * Preamble or Epilogue.
+                 */
+                textView.setText(o.toString());                
+            }
+            
+        }
+    }
+    
+    /**
+     * Creates and displays the gui.
+     * 
+     * @param message the Message to display in the tree.
+     */
+    private static void createAndShowGUI(Message message) {
+        /*
+         * Create and set up the window.
+         */
+        JFrame frame = new JFrame("MessageTree");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        /*
+         * Create and set up the content pane.
+         */
+        MessageTree newContentPane = new MessageTree(message);
+        newContentPane.setOpaque(true);
+        frame.setContentPane(newContentPane);
+
+        /*
+         * Display the window.
+         */
+        frame.pack();
+        frame.setVisible(true);
+    }
+    
+    public static void main(String[] args) {
+        try {
+            
+            final Message message = new Message(new FileInputStream(args[0]));
+            
+            javax.swing.SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
+                    createAndShowGUI(message);
+                }
+            });
+        
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.err.println("Wrong number of arguments.");
+            System.err.println("Usage: org.mime4j.samples.tree.MessageTree"
+                             + " path/to/message");
+        } catch (FileNotFoundException e) {
+            System.err.println("The file '" + args[0] + "' could not be found.");
+        } catch (IOException e) {
+            System.err.println("The file '" + args[0] + "' could not be read.");
+        }
+    }
+
+}