| /* |
| * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Distribution License v. 1.0, which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| import javax.mail.*; |
| import javax.mail.internet.*; |
| |
| /* |
| * Copy folder hierarchies between different Stores. This is a useful |
| * utility to populate new (and possibly empty) mail stores. Specify |
| * both the source and destination folders as URLs. |
| * |
| * @author John Mani |
| * @author Bill Shannon |
| */ |
| |
| public class populate { |
| |
| static boolean force = false; |
| static boolean skipSpecial = false; |
| static boolean clear = false; |
| static boolean dontPreserveFlags = false; |
| static boolean warn = false; |
| |
| public static void main(String argv[]) { |
| String srcURL = null; |
| String dstURL = null; |
| boolean debug = false; |
| |
| int optind; |
| |
| for (optind = 0; optind < argv.length; optind++) { |
| if (argv[optind].equals("-s")) { |
| srcURL = argv[++optind]; |
| } else if (argv[optind].equals("-d")) { |
| dstURL = argv[++optind]; |
| } else if (argv[optind].equals("-D")) { |
| debug = true; |
| } else if (argv[optind].equals("-f")) { |
| force = true; |
| } else if (argv[optind].equals("-S")) { |
| skipSpecial = true; |
| } else if (argv[optind].equals("-c")) { |
| clear = true; |
| } else if (argv[optind].equals("-P")) { |
| dontPreserveFlags = true; |
| } else if (argv[optind].equals("-W")) { |
| warn = true; |
| } else if (argv[optind].equals("--")) { |
| optind++; |
| break; |
| } else if (argv[optind].startsWith("-")) { |
| printUsage(); |
| System.exit(1); |
| } else { |
| break; |
| } |
| } |
| |
| try { |
| |
| if (srcURL == null || dstURL == null) { |
| printUsage(); |
| System.exit(1); |
| } |
| |
| Session session = Session.getInstance( |
| System.getProperties(), null); |
| session.setDebug(debug); |
| |
| // Get source folder |
| URLName srcURLName = new URLName(srcURL); |
| Folder srcFolder; |
| // Check if the source URL has a folder specified. If |
| // not, we use the default folder |
| if (srcURLName.getFile() == null) { |
| Store s = session.getStore(srcURLName); |
| s.connect(); |
| srcFolder = s.getDefaultFolder(); |
| } else { |
| srcFolder = session.getFolder(new URLName(srcURL)); |
| if (!srcFolder.exists()) { |
| System.out.println("source folder does not exist"); |
| srcFolder.getStore().close(); |
| System.exit(1); |
| } |
| } |
| |
| // Set up destination folder |
| URLName dstURLName = new URLName(dstURL); |
| Folder dstFolder; |
| // Check if the destination URL has a folder specified. If |
| // not, we use the source folder name |
| if (dstURLName.getFile() == null) { |
| Store s = session.getStore(dstURLName); |
| s.connect(); |
| dstFolder = s.getFolder(srcFolder.getName()); |
| } else |
| dstFolder = session.getFolder(dstURLName); |
| |
| if (clear && dstFolder.exists()) { |
| if (!dstFolder.delete(true)) { |
| System.out.println("couldn't delete " + |
| dstFolder.getFullName()); |
| return; |
| } |
| } |
| copy(srcFolder, dstFolder); |
| |
| // Close the respective stores. |
| srcFolder.getStore().close(); |
| dstFolder.getStore().close(); |
| |
| } catch (MessagingException mex) { |
| System.out.println(mex.getMessage()); |
| mex.printStackTrace(); |
| } |
| } |
| |
| private static void copy(Folder src, Folder dst) |
| throws MessagingException { |
| System.out.println("Populating " + dst.getFullName()); |
| |
| Folder ddst = dst; |
| Folder[] srcFolders = null; |
| if ((src.getType() & Folder.HOLDS_FOLDERS) != 0) |
| srcFolders = src.list(); |
| boolean srcHasChildren = srcFolders != null && srcFolders.length > 0; |
| |
| if (!dst.exists()) { |
| // Create it. |
| boolean dstHoldsOnlyFolders = false; |
| if (!dst.create(src.getType())) { |
| // might not be able to create a folder that holds both |
| if (!dst.create(srcHasChildren ? Folder.HOLDS_FOLDERS : |
| Folder.HOLDS_MESSAGES)) { |
| // might only be able to create one type (Gmail) |
| if (!dst.create(Folder.HOLDS_MESSAGES)) { |
| System.out.println("couldn't create " + |
| dst.getFullName()); |
| return; |
| } |
| } |
| dstHoldsOnlyFolders = srcHasChildren; |
| } |
| |
| // Copy over any messges from src to dst |
| if ((src.getType() & Folder.HOLDS_MESSAGES) != 0) { |
| src.open(Folder.READ_ONLY); |
| if (dstHoldsOnlyFolders) { |
| if (src.getMessageCount() > 0) { |
| System.out.println("Unable to copy messages from " + |
| src.getFullName() + " to " + dst.getFullName() + |
| " because destination holds only folders"); |
| } |
| } else |
| copyMessages(src, dst); |
| src.close(false); |
| } |
| } else { |
| System.out.println(dst.getFullName() + " already exists"); |
| // Copy over any messges from src to dst |
| if (force && (src.getType() & Folder.HOLDS_MESSAGES) != 0) { |
| src.open(Folder.READ_ONLY); |
| copyMessages(src, dst); |
| src.close(false); |
| } |
| } |
| |
| // Copy over subfolders |
| if (srcHasChildren) { |
| for (int i = 0; i < srcFolders.length; i++) { |
| // skip special directories? |
| if (skipSpecial) { |
| if (srcFolders[i].getName().equals("SCCS") || |
| srcFolders[i].getName().equals("Drafts") || |
| srcFolders[i].getName().equals("Trash") || |
| srcFolders[i].getName().equals("Shared Folders")) |
| continue; |
| } |
| copy(srcFolders[i], dst.getFolder(srcFolders[i].getName())); |
| } |
| } |
| } |
| |
| /** |
| * Copy message from src to dst. If dontPreserveFlags is set |
| * we first copy the messages to memory, clear all the flags, |
| * and then copy to the destination. |
| */ |
| private static void copyMessages(Folder src, Folder dst) |
| throws MessagingException { |
| Message[] msgs = src.getMessages(); |
| if (dontPreserveFlags) { |
| for (int i = 0; i < msgs.length; i++) { |
| MimeMessage m = new MimeMessage((MimeMessage)msgs[i]); |
| m.setFlags(m.getFlags(), false); |
| msgs[i] = m; |
| } |
| } |
| if (warn) { |
| // have to copy messages one at a time |
| for (int i = 0; i < msgs.length; i++) { |
| try { |
| src.copyMessages(new Message[] { msgs[i] }, dst); |
| } catch (MessagingException mex) { |
| System.out.println("WARNING: Copy of message " + (i + 1) + |
| " from " + src.getFullName() + |
| " to " + dst.getFullName() + |
| " failed: " + mex.toString()); |
| } |
| } |
| } else |
| src.copyMessages(msgs, dst); |
| } |
| |
| private static void printUsage() { |
| System.out.println("populate [-D] [-f] [-S] [-c] " + |
| "-s source_url -d dest_url"); |
| System.out.println("URLs are of the form: " + |
| "protocol://username:password@hostname/foldername"); |
| System.out.println("The destination URL does not need a foldername," + |
| " in which case, the source foldername is used"); |
| } |
| } |