📄 fetchmail.java
字号:
/*********************************************************************** * Copyright (c) 2003-2004 The Apache Software Foundation. * * All rights reserved. * * ------------------------------------------------------------------- * * Licensed under the Apache License, Version 2.0 (the "License"); you * * may not use this file except in compliance with the License. You * * may obtain a copy of the License at: * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * * implied. See the License for the specific language governing * * permissions and limitations under the License. * ***********************************************************************/package org.apache.james.fetchmail;import java.util.ArrayList;import java.util.Collections;import java.util.Enumeration;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Properties;import javax.mail.MessagingException;import javax.mail.Session;import org.apache.avalon.cornerstone.services.scheduler.Target;import org.apache.avalon.framework.configuration.Configurable;import org.apache.avalon.framework.configuration.Configuration;import org.apache.avalon.framework.configuration.ConfigurationException;import org.apache.avalon.framework.logger.AbstractLogEnabled;import org.apache.avalon.framework.service.ServiceException;import org.apache.avalon.framework.service.ServiceManager;import org.apache.james.services.MailServer;import org.apache.james.services.UsersRepository;import org.apache.james.services.UsersStore;/** * <p>Class <code>FetchMail</code> is an Avalon task that is periodically * triggered to fetch mail from a JavaMail Message Store.</p> * * <p>The lifecycle of an instance of <code>FetchMail</code> is managed by * Avalon. The <code>configure(Configuration)</code> method is invoked to parse * and validate Configuration properties. The targetTriggered(String) method is * invoked to execute the task.</p> * * <p>When triggered, a sorted list of Message Store Accounts to be processed is * built. Each Message Store Account is processed by delegating to * <code>StoreProcessor</code>.</p> * * <p>There are two kinds of Message Store Accounts, static and dynamic. Static * accounts are expliciltly declared in the Configuration. Dynamic accounts are * built each time the task is executed, one per each user defined to James, * using the James user name with a configurable prefix and suffix to define * the host user identity and recipient identity for each Account. Dynamic * accounts allow <code>FetchMail</code> to fetch mail for all James users * without modifying the Configuration parameters or restarting the Avalon * server.</p> * * <p>To fully understand the operations supported by this task, read the Class * documention for each Class in the delegation chain starting with this * class' delegate, <code>StoreProcessor</code>. </p> * * <p>Creation Date: 24-May-03</p> * */public class FetchMail extends AbstractLogEnabled implements Configurable, Target{ /** * Key fields for DynamicAccounts. */ private class DynamicAccountKey { /** * The base user name without prfix or suffix */ private String fieldUserName; /** * The sequence number of the parameters used to construct the Account */ private int fieldSequenceNumber; /** * Constructor for DynamicAccountKey. */ private DynamicAccountKey() { super(); } /** * Constructor for DynamicAccountKey. */ public DynamicAccountKey(String userName, int sequenceNumber) { this(); setUserName(userName); setSequenceNumber(sequenceNumber); } /** * @see java.lang.Object#equals(Object) */ public boolean equals(Object obj) { if (null == obj) return false; if (!(obj.getClass() == getClass())) return false; return ( getUserName().equals(((DynamicAccountKey) obj).getUserName()) && getSequenceNumber() == ((DynamicAccountKey) obj).getSequenceNumber()); } /** * @see java.lang.Object#hashCode() */ public int hashCode() { return getUserName().hashCode() ^ getSequenceNumber(); } /** * Returns the sequenceNumber. * @return int */ public int getSequenceNumber() { return fieldSequenceNumber; } /** * Returns the userName. * @return String */ public String getUserName() { return fieldUserName; } /** * Sets the sequenceNumber. * @param sequenceNumber The sequenceNumber to set */ protected void setSequenceNumber(int sequenceNumber) { fieldSequenceNumber = sequenceNumber; } /** * Sets the userName. * @param userName The userName to set */ protected void setUserName(String userName) { fieldUserName = userName; } } /** * Creation Date: 06-Jun-03 */ private class ParsedDynamicAccountParameters { private String fieldUserPrefix; private String fieldUserSuffix; private String fieldPassword; private int fieldSequenceNumber; private boolean fieldIgnoreRecipientHeader; private String fieldRecipientPrefix; private String fieldRecipientSuffix; /** * Constructor for ParsedDynamicAccountParameters. */ private ParsedDynamicAccountParameters() { super(); } /** * Constructor for ParsedDynamicAccountParameters. */ public ParsedDynamicAccountParameters( int sequenceNumber, Configuration configuration) throws ConfigurationException { this(); setSequenceNumber(sequenceNumber); setUserPrefix(configuration.getAttribute("userprefix", "")); setUserSuffix(configuration.getAttribute("usersuffix", "")); setRecipientPrefix(configuration.getAttribute("recipientprefix", "")); setRecipientSuffix(configuration.getAttribute("recipientsuffix", "")); setPassword(configuration.getAttribute("password")); setIgnoreRecipientHeader( configuration.getAttributeAsBoolean("ignorercpt-header")); } /** * Returns the recipientprefix. * @return String */ public String getRecipientPrefix() { return fieldRecipientPrefix; } /** * Returns the recipientsuffix. * @return String */ public String getRecipientSuffix() { return fieldRecipientSuffix; } /** * Returns the userprefix. * @return String */ public String getUserPrefix() { return fieldUserPrefix; } /** * Returns the userSuffix. * @return String */ public String getUserSuffix() { return fieldUserSuffix; } /** * Sets the recipientprefix. * @param recipientprefix The recipientprefix to set */ protected void setRecipientPrefix(String recipientprefix) { fieldRecipientPrefix = recipientprefix; } /** * Sets the recipientsuffix. * @param recipientsuffix The recipientsuffix to set */ protected void setRecipientSuffix(String recipientsuffix) { fieldRecipientSuffix = recipientsuffix; } /** * Sets the userprefix. * @param userprefix The userprefix to set */ protected void setUserPrefix(String userprefix) { fieldUserPrefix = userprefix; } /** * Sets the userSuffix. * @param userSuffix The userSuffix to set */ protected void setUserSuffix(String userSuffix) { fieldUserSuffix = userSuffix; } /** * Returns the password. * @return String */ public String getPassword() { return fieldPassword; } /** * Sets the ignoreRecipientHeader. * @param ignoreRecipientHeader The ignoreRecipientHeader to set */ protected void setIgnoreRecipientHeader(boolean ignoreRecipientHeader) { fieldIgnoreRecipientHeader = ignoreRecipientHeader; } /** * Sets the password. * @param password The password to set */ protected void setPassword(String password) { fieldPassword = password; } /** * Returns the ignoreRecipientHeader. * @return boolean */ public boolean isIgnoreRecipientHeader() { return fieldIgnoreRecipientHeader; } /** * Returns the sequenceNumber. * @return int */ public int getSequenceNumber() { return fieldSequenceNumber; } /** * Sets the sequenceNumber. * @param sequenceNumber The sequenceNumber to set */ protected void setSequenceNumber(int sequenceNumber) { fieldSequenceNumber = sequenceNumber; } } /** * @see org.apache.avalon.cornerstone.services.scheduler.Target#targetTriggered(String) */ private boolean fieldFetching = false; /** * The Configuration for this task */ private ParsedConfiguration fieldConfiguration; /** * A List of ParsedDynamicAccountParameters, one for every <alllocal> entry * in the configuration. */ private List fieldParsedDynamicAccountParameters; /** * The Static Accounts for this task. * These are setup when the task is configured. */ private List fieldStaticAccounts; /** * The JavaMail Session for this fetch task. */ private Session fieldSession; /** * The Dynamic Accounts for this task. * These are setup each time the fetchtask is run. */ private Map fieldDynamicAccounts; /** * The MailServer service */ private MailServer fieldServer; /** * The Local Users repository */ private UsersRepository fieldLocalUsers; /** * Constructor for POP3mail. */ public FetchMail() { super(); } /** * Method configure parses and validates the Configuration data and creates * a new <code>ParsedConfiguration</code>, an <code>Account</code> for each * configured static account and a <code>ParsedDynamicAccountParameters</code> * for each dynamic account. * * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) */ public void configure(Configuration configuration) throws ConfigurationException { // Set any Session parameters passed in the Configuration setSessionParameters(configuration); // Create the ParsedConfiguration used in the delegation chain ParsedConfiguration parsedConfiguration = new ParsedConfiguration( configuration, getLogger(), getServer(), getLocalUsers()); setConfiguration(parsedConfiguration); // Setup the Accounts Configuration[] allAccounts = configuration.getChildren("accounts"); if (allAccounts.length < 1) throw new ConfigurationException("Missing <accounts> section."); if (allAccounts.length > 1) throw new ConfigurationException("Too many <accounts> sections, there must be exactly one"); Configuration accounts = allAccounts[0]; // Create an Account for every configured account Configuration[] accountsChildren = accounts.getChildren(); if (accountsChildren.length < 1) throw new ConfigurationException("Missing <account> section."); for (int i = 0; i < accountsChildren.length; i++) { Configuration accountsChild = accountsChildren[i]; if (accountsChild.getName() == "alllocal") { // <allLocal> is dynamic, save the parameters for accounts to // be created when the task is triggered getParsedDynamicAccountParameters().add( new ParsedDynamicAccountParameters(i, accountsChild)); continue; } if (accountsChild.getName() == "account") { // Create an Account for the named user and // add it to the list of static accounts getStaticAccounts().add( new Account( i, parsedConfiguration, accountsChild.getAttribute("user"), accountsChild.getAttribute("password"), accountsChild.getAttribute("recipient"), accountsChild.getAttributeAsBoolean( "ignorercpt-header"), getSession())); continue; } throw new ConfigurationException( "Illegal token: <" + accountsChild.getName() + "> in <accounts>"); } } /** * Method target triggered fetches mail for each configured account. * * @see org.apache.avalon.cornerstone.services.scheduler.Target#targetTriggered(String) */ public void targetTriggered(String arg0) { // if we are already fetching then just return if (isFetching()) { getLogger().info( "Triggered fetch cancelled. A fetch is already in progress."); return; } // Enter Fetching State try { setFetching(true); getLogger().info("Fetcher starting fetches"); // if debugging, list the JavaMail property key/value pairs // for this Session if (getLogger().isDebugEnabled())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -