001: // The contents of this file are subject to the Mozilla Public License Version
002: // 1.1
003: //(the "License"); you may not use this file except in compliance with the
004: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
005: //
006: //Software distributed under the License is distributed on an "AS IS" basis,
007: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
008: //for the specific language governing rights and
009: //limitations under the License.
010: //
011: //The Original Code is "The Columba Project"
012: //
013: //The Initial Developers of the Original Code are Frederik Dietz and Timo
014: // Stich.
015: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
016: //
017: //All Rights Reserved.
018: package org.columba.mail.gui.config.subscribe;
019:
020: import java.util.ArrayList;
021: import java.util.Arrays;
022: import java.util.Enumeration;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import javax.swing.tree.DefaultMutableTreeNode;
027: import javax.swing.tree.DefaultTreeModel;
028: import javax.swing.tree.TreeNode;
029:
030: import org.columba.api.command.IWorkerStatusController;
031: import org.columba.core.base.ListTools;
032: import org.columba.core.command.Command;
033: import org.columba.mail.folder.imap.IMAPRootFolder;
034: import org.columba.mail.imap.IImapServer;
035: import org.columba.ristretto.imap.ListInfo;
036: import org.columba.ristretto.imap.Namespace;
037: import org.columba.ristretto.imap.NamespaceCollection;
038: import org.frapuccino.checkabletree.CheckableItemImpl;
039:
040: public class SynchronizeFolderListCommand extends Command {
041:
042: private IMAPRootFolder root;
043:
044: private IImapServer store;
045:
046: private TreeNode node;
047:
048: /**
049: * @param references
050: */
051: public SynchronizeFolderListCommand(
052: SubscribeCommandReference reference) {
053: super (reference);
054: }
055:
056: /*
057: * (non-Javadoc)
058: *
059: * @see org.columba.api.command.Command#execute(org.columba.api.command.Worker)
060: */
061: public void execute(IWorkerStatusController worker)
062: throws Exception {
063: root = (IMAPRootFolder) ((SubscribeCommandReference) getReference())
064: .getSourceFolder();
065:
066: store = root.getServer();
067:
068: node = createTreeStructure();
069: }
070:
071: private List fetchUnsubscribedFolders(String reference)
072: throws Exception {
073: NamespaceCollection namespaces;
074:
075: // Does the server support the namespace extension?
076: if (store.isSupported("NAMESPACE")) {
077: namespaces = store.fetchNamespaces();
078: } else {
079: // create default namespace
080: namespaces = new NamespaceCollection();
081: namespaces.addPersonalNamespace(new Namespace("", "/"));
082: }
083:
084: ArrayList result = new ArrayList();
085: Iterator it;
086:
087: // Process personal namespaces
088: if (namespaces.getPersonalNamespaceSize() > 0) {
089: it = namespaces.getPersonalIterator();
090: while (it.hasNext()) {
091: Namespace pN = (Namespace) it.next();
092:
093: ListInfo[] list = store.list("", pN.getPrefix() + '%');
094: result.addAll(Arrays.asList(list));
095: }
096: }
097:
098: // Process other users namespaces
099: if (namespaces.getOtherUserNamespaceSize() > 0) {
100: it = namespaces.getOtherUserIterator();
101: while (it.hasNext()) {
102: Namespace pN = (Namespace) it.next();
103:
104: ListInfo[] list = store.list("", pN.getPrefix() + '%');
105: result.addAll(Arrays.asList(list));
106: }
107: }
108:
109: // Process shared namespaces
110: if (namespaces.getSharedNamespaceSize() > 0) {
111: it = namespaces.getSharedIterator();
112: while (it.hasNext()) {
113: Namespace pN = (Namespace) it.next();
114:
115: ListInfo[] list = store.list("", pN.getPrefix() + '%');
116: result.addAll(Arrays.asList(list));
117: }
118: }
119:
120: for (int i = 0; i < result.size(); i++) {
121: ListInfo info = (ListInfo) result.get(i);
122: // Handle special case in which INBOX has a NIL delimiter
123: // -> there might exist a pseudo hierarchy under INBOX+delimiter
124: if (info.getName().equalsIgnoreCase("INBOX")
125: && info.getDelimiter() == null) {
126: result.addAll(Arrays.asList(store.list("", "INBOX"
127: + store.getDelimiter() + '%')));
128: break;
129: }
130:
131: // If this folder has children add them
132: // TODO: In the future we should try to fetch additional children on demand
133: // when the tree of the dialog is opened
134: if (info.getParameter(ListInfo.HASCHILDREN)) {
135: result.addAll(Arrays.asList(store.list("", info
136: .getName()
137: + store.getDelimiter() + '%')));
138: }
139: }
140:
141: return result;
142: }
143:
144: private TreeNode createTreeStructure() throws Exception {
145: ListInfo[] lsub = store.fetchSubscribedFolders();
146:
147: // Create list of unsubscribed folders
148: List subscribedFolders = new ArrayList(Arrays.asList(lsub));
149: // INBOX is always subscribed
150: subscribedFolders.add(new ListInfo("INBOX", null, 0));
151:
152: List unsubscribedFolders = fetchUnsubscribedFolders("");
153: ListTools.substract(unsubscribedFolders, subscribedFolders);
154:
155: // Now we have the subscribed folders in subscribedFolders
156: // and the unsubscribed folders in unsubscribedFolders
157: // Next step: Create a treestructure
158: CheckableItemImpl rootNode = new CheckableItemImpl(root
159: .getName());
160:
161: Iterator it = unsubscribedFolders.iterator();
162:
163: while (it.hasNext()) {
164: ListInfoTreeNode node = insertTreeNode(
165: (ListInfo) it.next(), rootNode);
166: node.setSelected(false);
167: }
168:
169: it = subscribedFolders.iterator();
170:
171: while (it.hasNext()) {
172: ListInfoTreeNode node = insertTreeNode(
173: (ListInfo) it.next(), rootNode);
174: node.setSelected(true);
175: }
176: return rootNode;
177: }
178:
179: private ListInfoTreeNode insertTreeNode(ListInfo listInfo,
180: DefaultMutableTreeNode parent) {
181: // split the hierarchical name with at the delimiters
182: String[] hierarchy = listInfo.getName().split(
183: "\\" + listInfo.getDelimiter());
184:
185: DefaultMutableTreeNode actParent = parent;
186: StringBuffer mailboxName = new StringBuffer();
187:
188: mailboxName.append(hierarchy[0]);
189: actParent = ensureChild(hierarchy[0], mailboxName.toString(),
190: actParent);
191:
192: for (int i = 1; i < hierarchy.length; i++) {
193: mailboxName.append(listInfo.getDelimiter());
194: mailboxName.append(hierarchy[i]);
195: actParent = ensureChild(hierarchy[i], mailboxName
196: .toString(), actParent);
197: }
198:
199: return (ListInfoTreeNode) actParent;
200: }
201:
202: private DefaultMutableTreeNode ensureChild(String name,
203: String mailbox, DefaultMutableTreeNode parent) {
204: Enumeration children = parent.children();
205: ListInfoTreeNode node;
206:
207: while (children.hasMoreElements()) {
208: node = (ListInfoTreeNode) children.nextElement();
209:
210: if (node.toString().equals(name)) {
211: return node;
212: }
213: }
214:
215: node = new ListInfoTreeNode(name, mailbox);
216: parent.add(node);
217:
218: return node;
219: }
220:
221: /*
222: * (non-Javadoc)
223: *
224: * @see org.columba.api.command.Command#updateGUI()
225: */
226: public void updateGUI() throws Exception {
227: SubscribeDialog dialog = ((SubscribeCommandReference) getReference())
228: .getDialog();
229:
230: dialog.syncFolderListDone(new DefaultTreeModel(node));
231: }
232: }
|