Source Code Cross Referenced for AbstractLocalFolder.java in  » Mail-Clients » columba-1.4 » org » columba » mail » folder » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Mail Clients » columba 1.4 » org.columba.mail.folder 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //The contents of this file are subject to the Mozilla Public License Version 1.1
002:        //(the "License"); you may not use this file except in compliance with the
003:        //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004:        //
005:        //Software distributed under the License is distributed on an "AS IS" basis,
006:        //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007:        //for the specific language governing rights and
008:        //limitations under the License.
009:        //
010:        //The Original Code is "The Columba Project"
011:        //
012:        //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013:        //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014:        //
015:        //All Rights Reserved.
016:
017:        package org.columba.mail.folder;
018:
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.io.InputStream;
022:        import java.util.ArrayList;
023:        import java.util.Arrays;
024:        import java.util.Collections;
025:        import java.util.LinkedList;
026:        import java.util.List;
027:        import java.util.logging.Logger;
028:
029:        import org.columba.core.base.ListTools;
030:        import org.columba.core.filter.FilterList;
031:        import org.columba.core.io.DiskIO;
032:        import org.columba.core.xml.XmlElement;
033:        import org.columba.mail.config.FolderItem;
034:        import org.columba.mail.folder.headercache.BerkeleyDBHeaderList;
035:        import org.columba.mail.folder.headercache.CachedHeaderfields;
036:        import org.columba.mail.folder.headercache.SyncHeaderList;
037:        import org.columba.mail.folder.search.DefaultSearchEngine;
038:        import org.columba.mail.message.ColumbaHeader;
039:        import org.columba.mail.message.ColumbaMessage;
040:        import org.columba.mail.message.IColumbaHeader;
041:        import org.columba.mail.message.IColumbaMessage;
042:        import org.columba.mail.message.IHeaderList;
043:        import org.columba.mail.message.IPersistantHeaderList;
044:        import org.columba.ristretto.io.Source;
045:        import org.columba.ristretto.io.SourceInputStream;
046:        import org.columba.ristretto.message.Attributes;
047:        import org.columba.ristretto.message.Flags;
048:        import org.columba.ristretto.message.Header;
049:        import org.columba.ristretto.message.LocalMimePart;
050:        import org.columba.ristretto.message.MimeTree;
051:        import org.columba.ristretto.parser.HeaderParser;
052:        import org.columba.ristretto.parser.MessageParser;
053:        import org.columba.ristretto.parser.ParserException;
054:
055:        /**
056:         * AbstractLocalFolder is a near-to working folder, which only needs a specific
057:         * {@link IDataStorage},{@link DefaultSearchEngine}and
058:         * {@link IHeaderListStorage}"plugged in" to make it work.
059:         * <p>
060:         * This class is abstract becaused, instead use {@link MHCachedFolder}a
061:         * complete implementation.
062:         * <p>
063:         * AbstractLocalFolder uses an internal {@link ColumbaMessage}object as cache.
064:         * This allows parsing of a message only once, while accessing the data of the
065:         * message multiple times.
066:         * <p>
067:         * Attribute <code>nextMessageUid</code> handles the next unique message ID.
068:         * When adding a new message to this folder, it gets this ID assigned for later
069:         * reference. Then nextMessageUid is simply increased.
070:         * <p>
071:         * 
072:         * @see org.columba.mail.folder.mh.MHCachedFolder
073:         * 
074:         * @author fdietz
075:         */
076:        public abstract class AbstractLocalFolder extends AbstractMessageFolder {
077:
078:            /** JDK 1.4+ logging framework logger, used for logging. */
079:            private static final Logger LOG = Logger
080:                    .getLogger("org.columba.mail.folder");
081:
082:            /**
083:             * the next messag which gets added to this folder receives this unique ID
084:             */
085:            protected int nextMessageUid = -1;
086:
087:            /**
088:             * we keep one message in cache in order to not needing to parse it twice
089:             * times
090:             */
091:            protected ColumbaMessage aktMessage;
092:
093:            private boolean firstOpen = true;
094:
095:            /**
096:             * implement your own mailbox format here
097:             */
098:
099:            protected IDataStorage dataStorage;
100:
101:            protected IPersistantHeaderList headerList;
102:
103:            /**
104:             * @param item
105:             *            <class>FolderItem </class> contains xml configuration of this
106:             *            folder
107:             */
108:            public AbstractLocalFolder(FolderItem item, String path) {
109:                super (item, path);
110:
111:                // TODO (@author fdietz): move this to AbstractMessageFolder constructor
112:                // create filterlist datastructure
113:                XmlElement filterListElement = node
114:                        .getElement(FilterList.XML_NAME);
115:
116:                if (filterListElement == null) {
117:                    // no filterlist treenode found
118:                    // -> create a new one
119:                    filterListElement = new XmlElement(FilterList.XML_NAME);
120:                    getConfiguration().getRoot().addElement(filterListElement);
121:                }
122:
123:                filterList = new FilterList(filterListElement);
124:
125:                setSearchEngine(new DefaultSearchEngine(this ));
126:            }
127:
128:            /**
129:             * @param name
130:             *            the name of the folder.
131:             * @param type
132:             *            type of folder.
133:             */
134:            public AbstractLocalFolder(String name, String type, String path) {
135:                super (name, type, path);
136:
137:                // create filterlist datastructure
138:                XmlElement filterListElement = node
139:                        .getElement(FilterList.XML_NAME);
140:
141:                if (filterListElement == null) {
142:                    // no filterlist treenode found
143:                    // -> create a new one
144:                    filterListElement = new XmlElement(FilterList.XML_NAME);
145:                    getConfiguration().getRoot().addElement(filterListElement);
146:                }
147:
148:                filterList = new FilterList(filterListElement);
149:
150:                setSearchEngine(new DefaultSearchEngine(this ));
151:            }
152:
153:            /**
154:             * Remove folder from tree
155:             * 
156:             * @see org.columba.mail.folder.FolderTreeNode#removeFolder()
157:             */
158:            public void removeFolder() throws Exception {
159:                // delete folder from your harddrive
160:                boolean b = DiskIO.deleteDirectory(directoryFile);
161:
162:                // if this worked, remove it from tree.xml configuration, too
163:                if (b) {
164:                    super .removeFolder();
165:                }
166:            }
167:
168:            /**
169:             * 
170:             * Generate new unique message ID
171:             * 
172:             * @return <class>Integer </class> containing UID
173:             */
174:            protected Object generateNextMessageUid() {
175:                if (nextMessageUid == -1) {
176:                    try {
177:                        if (getHeaderList().count() > 0) {
178:                            List _headerList = new ArrayList();
179:                            Object[] _uidList = headerList.getUids();
180:                            for (int i = 0; i < _uidList.length; i++) {
181:                                _headerList.add(_uidList[i]);
182:                            }
183:                            Integer maxUid = (Integer) Collections
184:                                    .max(_headerList);
185:                            nextMessageUid = maxUid.intValue() + 1;
186:                        } else {
187:                            nextMessageUid = 0;
188:                        }
189:                    } catch (Exception e) {
190:                        nextMessageUid = 0;
191:                    }
192:                }
193:
194:                return new Integer(nextMessageUid++);
195:            }
196:
197:            /**
198:             * 
199:             * Set next unique message ID
200:             * 
201:             * @param next
202:             *            number of next message
203:             */
204:            public void setNextMessageUid(int next) {
205:                nextMessageUid = next;
206:            }
207:
208:            /**
209:             * 
210:             * Implement a <class>IDataStorage </class> for the mailbox format of your
211:             * pleasure.
212:             * 
213:             * @return instance of <class>IDataStorage </class>
214:             */
215:            public abstract IDataStorage getDataStorageInstance();
216:
217:            /**
218:             * @see org.columba.mail.folder.IMailbox#getMimePartTree(java.lang.Object)
219:             */
220:            public MimeTree getMimePartTree(Object uid) throws Exception {
221:                // get message with UID
222:                IColumbaMessage message = getMessage(uid);
223:
224:                // get tree-like structure of mimeparts
225:                MimeTree mptree = message.getMimePartTree();
226:
227:                return mptree;
228:            }
229:
230:            /** {@inheritDoc} */
231:            public InputStream getMessageSourceStream(Object uid)
232:                    throws Exception {
233:                return getDataStorageInstance().getMessageStream(uid);
234:            }
235:
236:            /** {@inheritDoc} */
237:            public InputStream getMimePartBodyStream(Object uid,
238:                    Integer[] address) throws Exception {
239:                // get message with UID
240:                IColumbaMessage message = getMessage(uid);
241:
242:                // Get the mimepart
243:                LocalMimePart mimepart = (LocalMimePart) message
244:                        .getMimePartTree().getFromAddress(address);
245:
246:                return mimepart.getInputStream();
247:            }
248:
249:            /** {@inheritDoc} */
250:            public InputStream getMimePartSourceStream(Object uid,
251:                    Integer[] address) throws Exception {
252:                // get message with UID
253:                IColumbaMessage message = getMessage(uid);
254:
255:                // Get the mimepart
256:                LocalMimePart mimepart = (LocalMimePart) message
257:                        .getMimePartTree().getFromAddress(address);
258:
259:                return new SourceInputStream(mimepart.getSource());
260:            }
261:
262:            /**
263:             * Copies a set of messages from this folder to a destination folder.
264:             * <p>
265:             * First we copy the message source to the destination folder. Then we also
266:             * copy the flags attribute of this message.
267:             * 
268:             * @see org.columba.mail.folder.IMailbox#innerCopy(org.columba.mail.folder.IMailbox,
269:             *      java.lang.Object[])
270:             */
271:            public void innerCopy(IMailbox destFolder, Object[] uids)
272:                    throws Exception {
273:                if (getObservable() != null) {
274:                    getObservable().setMax(uids.length);
275:                }
276:
277:                for (int i = 0; i < uids.length; i++) {
278:                    // skip this message, if it doesn't exist in source folder
279:                    if (!exists(uids[i])) {
280:                        continue;
281:                    }
282:
283:                    InputStream messageSourceStream = getMessageSourceStream(uids[i]);
284:                    destFolder.addMessage(messageSourceStream,
285:                            getAttributes(uids[i]), getFlags(uids[i]));
286:                    messageSourceStream.close();
287:
288:                    /*
289:                     * ((AbstractLocalFolder) destFolder).setFlags(destuid, (Flags)
290:                     * getFlags( uids[i]).clone());
291:                     */
292:                    // destFolder.fireMessageAdded(uids[i]);
293:                    if (getObservable() != null) {
294:                        getObservable().setCurrent(i);
295:                    }
296:                }
297:
298:                // we are done - clear the progress bar
299:                if (getObservable() != null) {
300:                    getObservable().resetCurrent();
301:                }
302:            }
303:
304:            public Object addMessage(InputStream in) throws Exception {
305:                return addMessage(in, null, null);
306:            }
307:
308:            public Object addMessage(InputStream in, Attributes attributes,
309:                    Flags flags) throws Exception {
310:                // generate UID for new message
311:                Object newUid = generateNextMessageUid();
312:
313:                // save message stream to file
314:                getDataStorageInstance().saveMessage(newUid, in);
315:
316:                // close stream
317:                in.close();
318:
319:                // parse header
320:                Source source = getDataStorageInstance().getMessageSource(
321:                        newUid);
322:                int messageSize = source.length();
323:
324:                Header header = HeaderParser.parse(source);
325:                ColumbaHeader h;
326:                if ((attributes != null) && (flags != null)) {
327:                    // save header and attributes. Copy the flags!
328:                    h = new ColumbaHeader(header, (Attributes) attributes
329:                            .clone(), new Flags(flags.getFlags()));
330:                } else {
331:                    h = new ColumbaHeader(header);
332:                    h.set("columba.size", new Integer(messageSize / 1024));
333:                }
334:                source.close();
335:                h.set("columba.uid", newUid);
336:                getHeaderList().add(h, newUid);
337:
338:                fireMessageAdded(newUid, getFlags(newUid));
339:                return newUid;
340:            }
341:
342:            /** {@inheritDoc} */
343:            public boolean isInboxFolder() {
344:                return getId().equals("101");
345:            }
346:
347:            /** {@inheritDoc} */
348:            public boolean isTrashFolder() {
349:                return getId().equals("105");
350:            }
351:
352:            /** {@inheritDoc} */
353:            public boolean supportsAddFolder(String newFolderType) {
354:                return (FolderFactory.getInstance().getGroup(newFolderType)
355:                        .equals("local") || newFolderType
356:                        .equals("VirtualFolder"));
357:            }
358:
359:            /**
360:             * Returns true since local folders can be moved.
361:             * 
362:             * @return true.
363:             */
364:            public boolean supportsMove() {
365:                return true;
366:            }
367:
368:            /**
369:             * @param uid
370:             * @return
371:             * @throws Exception
372:             */
373:            protected ColumbaMessage getMessage(Object uid) throws Exception {
374:                // Check if the message is already cached
375:                if (aktMessage != null) {
376:                    if (aktMessage.getUID().equals(uid)) {
377:                        // this message is already cached
378:                        return aktMessage;
379:                    }
380:                }
381:
382:                ColumbaMessage message;
383:
384:                try {
385:
386:                    Source source = null;
387:
388:                    source = getDataStorageInstance().getMessageSource(uid);
389:
390:                    // Parse Message from DataStorage
391:                    try {
392:                        message = new ColumbaMessage(MessageParser
393:                                .parse(source));
394:                    } catch (ParserException e1) {
395:                        LOG.fine(e1.getSource().toString());
396:                        throw e1;
397:                    }
398:                    source.close();
399:
400:                    message.setUID(uid);
401:
402:                    aktMessage = message;
403:
404:                    // TODO: fix parser exception
405:                } catch (FolderInconsistentException e) {
406:                    super .removeMessage(uid);
407:
408:                    throw e;
409:                }
410:
411:                // We use the attributes and flags from the cache
412:                // but the parsed header from the parsed message
413:                IColumbaHeader header = getHeaderList().get(uid);
414:                header.setHeader(message.getHeader().getHeader());
415:                message.setHeader(header);
416:
417:                return message;
418:            }
419:
420:            /**
421:             * @see org.columba.mail.folder.IMailbox#getMessageHeader(java.lang.Object)
422:             * @TODO dont use deprecated method
423:             */
424:            protected IColumbaHeader getMessageHeader(Object uid)
425:                    throws Exception {
426:                if ((aktMessage != null) && (aktMessage.getUID().equals(uid))) {
427:                    // message is already cached
428:                    // try to compare the headerfield count of
429:                    // the actually parsed message with the cached
430:                    // headerfield count
431:                    IColumbaMessage message = getMessage(uid);
432:
433:                    // number of headerfields
434:                    int size = message.getHeader().count();
435:
436:                    // get header from cache
437:                    IColumbaHeader h = getHeaderList().get(uid);
438:
439:                    // message doesn't exist (this shouldn't happen here)
440:                    if (h == null) {
441:                        return null;
442:                    }
443:
444:                    // number of headerfields
445:                    int cachedSize = h.count();
446:
447:                    // if header contains more fields than the cached header
448:                    if (size > cachedSize) {
449:                        return (ColumbaHeader) message.getHeader();
450:                    }
451:
452:                    return (ColumbaHeader) h;
453:                } else {
454:                    // message isn't cached
455:                    // -> just return header from cache
456:                    return getHeaderList().get(uid);
457:                }
458:            }
459:
460:            /**
461:             * @see org.columba.mail.folder.IMailbox#remove(java.lang.Object)
462:             */
463:            public void removeMessage(Object uid) throws Exception {
464:                // remove message from disk
465:                getDataStorageInstance().removeMessage(uid);
466:
467:                // fireMessageRemoved(uid, getFlags(uid));
468:                super .removeMessage(uid);
469:
470:            }
471:
472:            /**
473:             * Changes the selected message flags and updates the {@link MailFolderInfo}
474:             * accordingly.
475:             * <p>
476:             * This method is only used for innerCopy().
477:             * 
478:             * @param uid
479:             *            selected message UID
480:             * @param flags
481:             *            new flags
482:             * @throws Exception
483:             */
484:            protected void setFlags(Object uid, Flags flags) throws Exception {
485:                IColumbaHeader h = getHeaderList().get(uid);
486:
487:                Flags oldFlags = h.getFlags();
488:                h.setFlags(flags);
489:
490:                // update MessageFolderInfo
491:                if (oldFlags.get(Flags.RECENT) && !flags.get(Flags.RECENT)) {
492:                    getMessageFolderInfo().decRecent();
493:                }
494:
495:                if (!oldFlags.get(Flags.RECENT) && flags.get(Flags.RECENT)) {
496:                    getMessageFolderInfo().incRecent();
497:                }
498:
499:                if (oldFlags.get(Flags.SEEN) && !flags.get(Flags.SEEN)) {
500:                    getMessageFolderInfo().incUnseen();
501:                }
502:
503:                if (!oldFlags.get(Flags.SEEN) && flags.get(Flags.SEEN)) {
504:                    getMessageFolderInfo().decUnseen();
505:                }
506:            }
507:
508:            /**
509:             * This method first tries to find the requested header in the header cache.
510:             * If the headerfield is not cached, the message source is parsed.
511:             * 
512:             * @see org.columba.mail.folder.IMailbox#getHeaderFields(java.lang.Object,
513:             *      java.lang.String[])
514:             * 
515:             */
516:            public Header getHeaderFields(Object uid, String[] keys)
517:                    throws Exception {
518:                // cached headerfield list
519:                List cachedList = Arrays.asList(CachedHeaderfields
520:                        .getDefaultHeaderfields());
521:
522:                LinkedList keyList = new LinkedList(Arrays.asList(keys));
523:
524:                ListTools.substract(keyList, cachedList);
525:
526:                if (keyList.size() == 0) {
527:                    return getHeaderList().get(uid).getHeader();
528:                } else {
529:                    // We need to parse
530:                    // get message with UID
531:                    IColumbaMessage message = getMessage(uid);
532:
533:                    Header header = message.getHeader().getHeader();
534:
535:                    Header subHeader = new Header();
536:                    String value;
537:
538:                    for (int i = 0; i < keys.length; i++) {
539:                        value = header.get(keys[i]);
540:
541:                        if (value != null) {
542:                            subHeader.set(keys[i], value);
543:                        }
544:                    }
545:
546:                    return subHeader;
547:                }
548:            }
549:
550:            /**
551:             * @see org.columba.mail.folder.IMailbox#expungeFolder()
552:             */
553:            public void expungeFolder() throws Exception {
554:                // make sure to close all file handles
555:                // to the currently cached message
556:                // -> necessary for windows to be able to delete the local file
557:                if (aktMessage != null) {
558:                    aktMessage.close();
559:                    aktMessage = null;
560:                }
561:
562:                super .expungeFolder();
563:            }
564:
565:            /**
566:             * @see org.columba.mail.folder.IMailbox#getAllHeaderFields(java.lang.Object)
567:             */
568:            public Header getAllHeaderFields(Object uid) throws Exception {
569:
570:                IColumbaMessage message = getMessage(uid);
571:
572:                Header header = message.getHeader().getHeader();
573:
574:                return header;
575:            }
576:
577:            public synchronized IHeaderList getHeaderList() throws Exception {
578:                if (headerList == null) {
579:                    // header cache is stored in "headerlist" subfolder
580:                    File headercacheDirectory = new File(getDirectoryFile(),
581:                            "headerlist");
582:                    headerList = new BerkeleyDBHeaderList(headercacheDirectory,
583:                            getId());
584:                    final AbstractMessageFolder folder = this ;
585:                    headerList
586:                            .addHeaderListCorruptedListener(new IHeaderListCorruptedListener() {
587:
588:                                public void headerListCorrupted(
589:                                        IHeaderList headerList) {
590:                                    try {
591:                                        SyncHeaderList.sync(folder, headerList);
592:                                    } catch (IOException e) {
593:                                        LOG.severe(e.getMessage());
594:                                    }
595:                                }
596:                            });
597:                }
598:
599:                if (firstOpen) {
600:
601:                    if (headerList.count() != getDataStorageInstance()
602:                            .getMessageCount()) {
603:                        // Must be out of sync!
604:                        SyncHeaderList.sync(this , headerList);
605:                    }
606:
607:                    firstOpen = false;
608:                }
609:
610:                return headerList;
611:            }
612:
613:            /**
614:             * @see org.columba.mail.folder.AbstractMessageFolder#save()
615:             */
616:            public void save() throws Exception {
617:                super .save();
618:                if (headerList != null)
619:                    headerList.persist();
620:            }
621:
622:            /*
623:             * (non-Javadoc)
624:             * 
625:             * @see org.columba.mail.folder.AbstractMessageFolder#loadMessageFolderInfo()
626:             */
627:            protected void loadMessageFolderInfo() {
628:                super .loadMessageFolderInfo();
629:
630:                int storedCount = getDataStorageInstance().getMessageCount();
631:                // Check if still consistent
632:                if (messageFolderInfo.getExists() != storedCount) {
633:                    recreateMessageFolderInfo();
634:                }
635:
636:            }
637:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.