📄 remotedelivery.java
字号:
} catch (Exception ignored) {} // wait for James to finish initializing } //Checks the pool and delivers a mail message Properties props = new Properties(); //Not needed for production environment props.put("mail.debug", "false"); //Prevents problems encountered with 250 OK Messages props.put("mail.smtp.ehlo", "false"); //Sets timeout on going connections props.put("mail.smtp.timeout", smtpTimeout + ""); props.put("mail.smtp.connectiontimeout", connectionTimeout + ""); props.put("mail.smtp.sendpartial",String.valueOf(sendPartial)); //Set the hostname we'll use as this server if (getMailetContext().getAttribute(Constants.HELLO_NAME) != null) { props.put("mail.smtp.localhost", (String) getMailetContext().getAttribute(Constants.HELLO_NAME)); } else { Collection servernames = (Collection) getMailetContext().getAttribute(Constants.SERVER_NAMES); if ((servernames != null) && (servernames.size() > 0)) { props.put("mail.smtp.localhost", (String) servernames.iterator().next()); } } if (isBindUsed) { // undocumented JavaMail 1.2 feature, smtp transport will use // our socket factory, which will also set the local address props.put("mail.smtp.socketFactory.class", "org.apache.james.transport.mailets.RemoteDeliverySocketFactory"); // Don't fallback to the standard socket factory on error, do throw an exception props.put("mail.smtp.socketFactory.fallback", "false"); } Session session = Session.getInstance(props, null); try { while (!Thread.currentThread().interrupted() && !destroyed) { try { MailImpl mail = (MailImpl)outgoing.accept(delayFilter); String key = mail.getName(); try { if (isDebug) { StringBuffer logMessageBuffer = new StringBuffer(128) .append(Thread.currentThread().getName()) .append(" will process mail ") .append(key); log(logMessageBuffer.toString()); } if (deliver(mail, session)) { //Message was successfully delivered/fully failed... delete it outgoing.remove(key); } else { //Something happened that will delay delivery. Store any updates outgoing.store(mail); } //Clear the object handle to make sure it recycles this object. mail = null; } catch (Exception e) { // Prevent unexpected exceptions from causing looping by removing // message from outgoing. outgoing.remove(key); throw e; } } catch (Throwable e) { if (!destroyed) log("Exception caught in RemoteDelivery.run()", e); } } } finally { // Restore the thread state to non-interrupted. Thread.currentThread().interrupted(); } } /** * @param list holding Delay objects * @return the total attempts for all delays **/ private int calcTotalAttempts (ArrayList list) { int sum = 0; Iterator i = list.iterator(); while (i.hasNext()) { Delay delay = (Delay)i.next(); sum += delay.getAttempts(); } return sum; } /** * This method expands an ArrayList containing Delay objects into an array holding the * only delaytime in the order.<p> * So if the list has 2 Delay objects the first having attempts=2 and delaytime 4000 * the second having attempts=1 and delaytime=300000 will be expanded into this array:<p> * long[0] = 4000<p> * long[1] = 4000<p> * long[2] = 300000<p> * @param list the list to expand * @return the expanded list **/ private long[] expandDelays (ArrayList list) { long[] delays = new long [calcTotalAttempts(list)]; Iterator i = list.iterator(); int idx = 0; while (i.hasNext()) { Delay delay = (Delay)i.next(); for (int j=0; j<delay.getAttempts(); j++) { delays[idx++]= delay.getDelayTime(); } } return delays; } /** * This method returns, given a retry-count, the next delay time to use. * @param retry_count the current retry_count. * @return the next delay time to use, given the retry count **/ private long getNextDelay (int retry_count) { return delayTimes[retry_count-1]; } /** * This class is used to hold a delay time and its corresponding number * of retries. **/ private class Delay { private int attempts = 1; private long delayTime = DEFAULT_DELAY_TIME; /** * This constructor expects Strings of the form "[attempt\*]delaytime[unit]". <p> * The optional attempt is the number of tries this delay should be used (default = 1) * The unit if present must be one of (msec,sec,minute,hour,day) (default = msec) * The constructor multiplies the delaytime by the relevant multiplier for the unit, * so the delayTime instance variable is always in msec. * @param init_string the string to initialize this Delay object from **/ public Delay (String init_string) throws MessagingException { String unit = "msec"; //default unit if (delayTimeMatcher.matches (init_string, PATTERN)) { MatchResult res = delayTimeMatcher.getMatch (); //the capturing groups will now hold //at 1: attempts * (if present) //at 2: delaytime //at 3: unit (if present) if (res.group(1) != null && !res.group(1).equals ("")) { //we have an attempt * String attempt_match = res.group(1); //strip the * and whitespace attempt_match = attempt_match.substring (0,attempt_match.length()-1).trim(); attempts = Integer.parseInt (attempt_match); } delayTime = Long.parseLong (res.group(2)); if (!res.group(3).equals ("")) { //we have a unit unit = res.group(3).toLowerCase(); } } else { throw new MessagingException(init_string+" does not match "+PATTERN_STRING); } if (MULTIPLIERS.get (unit)!=null) { int multiplier = ((Integer)MULTIPLIERS.get (unit)).intValue(); delayTime *= multiplier; } else { throw new MessagingException("Unknown unit: "+unit); } } /** * This constructor makes a default Delay object, ie. attempts=1 and delayTime=DEFAULT_DELAY_TIME **/ public Delay () { } /** * @return the delayTime for this Delay **/ public long getDelayTime () { return delayTime; } /** * @return the number attempts this Delay should be used. **/ public int getAttempts () { return attempts; } /** * Set the number attempts this Delay should be used. **/ public void setAttempts (int value) { attempts = value; } /** * Pretty prints this Delay **/ public String toString () { StringBuffer buf = new StringBuffer(15); buf.append (getAttempts ()); buf.append ('*'); buf.append (getDelayTime()); buf.append ("msec"); return buf.toString(); } } /* * Returns an Iterator over org.apache.mailet.HostAddress, a * specialized subclass of javax.mail.URLName, which provides * location information for servers that are specified as mail * handlers for the given hostname. If no host is found, the * Iterator returned will be empty and the first call to hasNext() * will return false. The Iterator is a nested iterator: the outer * iteration is over each gateway, and the inner iteration is over * potentially multiple A records for each gateway. * * @see org.apache.james.DNSServer#getSMTPHostAddresses(String) * @since v2.2.0a16-unstable * @param gatewayServers - Collection of host[:port] Strings * @return an Iterator over HostAddress instances, sorted by priority */ private Iterator getGatewaySMTPHostAddresses(final Collection gatewayServers) { return new Iterator() { private Iterator gateways = gatewayServers.iterator(); private Iterator addresses = null; public boolean hasNext() { return gateways.hasNext(); } public Object next() { if (addresses == null || !addresses.hasNext()) { String server = (String) gateways.next(); String port = "25"; int idx = server.indexOf(':'); if ( idx > 0) { port = server.substring(idx+1); server = server.substring(0,idx); } final String nextGateway = server; final String nextGatewayPort = port; try { final InetAddress[] ips = org.apache.james.dnsserver.DNSServer.getAllByName(nextGateway); addresses = new Iterator() { private InetAddress[] ipAddresses = ips; int i = 0; public boolean hasNext() { return i < ipAddresses.length; } public Object next() { return new org.apache.mailet.HostAddress(nextGateway, "smtp://" + (ipAddresses[i++]).getHostAddress() + ":" + nextGatewayPort); } public void remove() { throw new UnsupportedOperationException ("remove not supported by this iterator"); } }; } catch (java.net.UnknownHostException uhe) { log("Unknown gateway host: " + uhe.getMessage().trim()); log("This could be a DNS server error or configuration error."); } } return (addresses != null) ? addresses.next() : null; } public void remove() { throw new UnsupportedOperationException ("remove not supported by this iterator"); } }; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -