protected Message getNextMessage() throws MessagingException { if (getMessageCount() > 0) { Message message = folder.getMessage(1); if (!message.isExpunged()) { return message; } } return null; }
private boolean isRead(Message msg, String context) { boolean readFlag = false; try { if (msg.isExpunged()) { readFlag = true; } else { Flags flags = msg.getFlags(); Flags.Flag[] flag = flags.getSystemFlags(); for (Flags.Flag aFlag : flag) { if (aFlag == Flags.Flag.SEEN) { readFlag = true; break; } } } } catch (MessagingException e) { log.debug(String.format("failed to get SEEN FLAG for %s", context), e); } return readFlag; }
@Override protected Iterator<MultiValueHashMap<String, Object>> getSubDataEntitiesInformation( InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws Exception { // imap url schema: imap[s]://uname@hostname:port/folder;uidvalidity=385759045/;uid=20. Examples // (incl. message-referenzierung) // http://xml.resource.org/public/rfc/html/rfc2192.html#anchor10 // allerdings nimmt der Java ImapStore auch URLs mit Passwörtern an. Dann geht auch // imap[s]://uname:pwd@hostname:port/folder;uidvalidity=385759045/;uid=20 CrawlerContext crawlerContext = context.get(CrawlerContext.class, new CrawlerContext()); String strContainerURL = metadata.get(Metadata.SOURCE); URLName containerURLName = new URLName(strContainerURL); if (m_mailStore == null) m_mailStore = connect2Server(containerURLName, context); // wenn kein directory angegeben wird, dann crawlen wir einfach den default folder und die inbox LinkedList<Folder> llFolderz2Crawl = new LinkedList<Folder>(); if (containerURLName.getFile() != null) { Folder folder = m_mailStore.getFolder(containerURLName.getFile()); if (folder != null && folder.exists()) llFolderz2Crawl.add(folder); else throw new FileNotFoundException("Can't find imap folder '" + folder.getFullName() + "'"); } else { Folder folder = m_mailStore.getDefaultFolder(); if (folder != null && folder.exists()) llFolderz2Crawl.add(folder); folder = m_mailStore.getFolder("INBOX"); if (folder != null && folder.exists()) llFolderz2Crawl.add(folder); } LinkedList<MultiValueHashMap<String, Object>> llEntityInfo = new LinkedList<MultiValueHashMap<String, Object>>(); for (Folder folder2crawl : llFolderz2Crawl) { // Jetzt haben wir die Containerobjekte - nun geben wir die Daten zu den SubEntities zurück // die subfolder boolean bFolderCanHaveSubFolders = (folder2crawl.getType() & Folder.HOLDS_FOLDERS) == Folder.HOLDS_FOLDERS; if (bFolderCanHaveSubFolders) { folder2crawl.open(Folder.READ_ONLY); Folder[] subFolders = folder2crawl.list(); for (Folder subFolder : subFolders) { URLName urlName = subFolder.getURLName(); URLName urlNameWithPassword = new URLName( containerURLName.getProtocol(), urlName.getHost(), urlName.getPort(), urlName.getFile(), urlName.getUsername(), containerURLName.getPassword()); if (!checkIfInConstraints(urlName.toString(), null, context)) continue; MultiValueHashMap<String, Object> hsEntityInformation = new MultiValueHashMap<String, Object>(); hsEntityInformation.add(CrawlerParser.SOURCEID, urlName); hsEntityInformation.add("urlNameWithPassword", urlNameWithPassword); hsEntityInformation.add("folder", subFolder.getFullName()); llEntityInfo.add(hsEntityInformation); } } // die messages boolean bFolderCanHaveMessages = (folder2crawl.getType() & Folder.HOLDS_MESSAGES) == Folder.HOLDS_MESSAGES; if (bFolderCanHaveMessages) { if (!folder2crawl.isOpen()) folder2crawl.open(Folder.READ_ONLY); // wir holen uns alle nicht-deleted messages, und werfen noch die raus, die 'expunged' sind Message[] relevantMessagesOfFolder = folder2crawl.search(new FlagTerm(new Flags(Flags.Flag.DELETED), false)); ArrayList<Message> nonDelNonExpungedMessages = new ArrayList<Message>(); for (Message message : relevantMessagesOfFolder) if (!message.isExpunged()) nonDelNonExpungedMessages.add(message); relevantMessagesOfFolder = nonDelNonExpungedMessages.toArray(new Message[0]); // die Daten die wir später benötigen holen wir uns effizient in einem Rutsch - deswegen // benötigen wir auch keinen Thread mit dem // OneAfterOneIterator, um Speicher zu sparen (siehe DirectoryCrawlerParser). Das Array // haben wir hier eh. Entweder oder. FetchProfile profile = new FetchProfile(); profile.add(UIDFolder.FetchProfileItem.UID); profile.add("Message-ID"); folder2crawl.fetch(relevantMessagesOfFolder, profile); for (int i = 0; i < relevantMessagesOfFolder.length && !crawlerContext.stopRequested(); i++) { MimeMessage message = (MimeMessage) relevantMessagesOfFolder[i]; // hier brauchen wir noch eine URL mit und eine ohne Passwort URLName urlName = getMessageUrl(folder2crawl, message); URLName urlNameWithPassword = new URLName( containerURLName.getProtocol(), urlName.getHost(), urlName.getPort(), urlName.getFile(), urlName.getUsername(), containerURLName.getPassword()); if (!checkIfInConstraints(urlName.toString(), message, context)) continue; MultiValueHashMap<String, Object> hsEntityInformation = new MultiValueHashMap<String, Object>(); hsEntityInformation.add(CrawlerParser.SOURCEID, urlName); hsEntityInformation.add("urlNameWithPassword", urlNameWithPassword); hsEntityInformation.add("Message-ID", message.getHeader("Message-ID")[0]); hsEntityInformation.add("folder", folder2crawl.getFullName()); llEntityInfo.add(hsEntityInformation); } } // wir haben die folder abgearbeitet, dann können wir diesen Speicher wieder frei geben m_hsImapFolder2Stickyness.clear(); if (folder2crawl.isOpen()) folder2crawl.close(false); } return llEntityInfo.iterator(); }