001    /****************************************************************
002     * Licensed to the Apache Software Foundation (ASF) under one   *
003     * or more contributor license agreements.  See the NOTICE file *
004     * distributed with this work for additional information        *
005     * regarding copyright ownership.  The ASF licenses this file   *
006     * to you under the Apache License, Version 2.0 (the            *
007     * "License"); you may not use this file except in compliance   *
008     * with the License.  You may obtain a copy of the License at   *
009     *                                                              *
010     *   http://www.apache.org/licenses/LICENSE-2.0                 *
011     *                                                              *
012     * Unless required by applicable law or agreed to in writing,   *
013     * software distributed under the License is distributed on an  *
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015     * KIND, either express or implied.  See the License for the    *
016     * specific language governing permissions and limitations      *
017     * under the License.                                           *
018     ****************************************************************/
019    
020    package org.apache.james.jspf.executor;
021    
022    import org.apache.james.jspf.core.DNSLookupContinuation;
023    import org.apache.james.jspf.core.DNSResponse;
024    import org.apache.james.jspf.core.DNSService;
025    import org.apache.james.jspf.core.Logger;
026    import org.apache.james.jspf.core.SPFChecker;
027    import org.apache.james.jspf.core.SPFCheckerExceptionCatcher;
028    import org.apache.james.jspf.core.SPFSession;
029    import org.apache.james.jspf.core.exceptions.SPFResultException;
030    import org.apache.james.jspf.core.exceptions.TimeoutException;
031    
032    /**
033     * Synchronous implementation of SPFExecuter. All queries will get executed synchronously
034     */
035    public class SynchronousSPFExecutor implements SPFExecutor {
036        
037        private Logger log;
038        private DNSService dnsProbe;
039    
040        public SynchronousSPFExecutor(Logger log, DNSService service) {
041            this.log = log;
042            this.dnsProbe = service;
043        }
044    
045        /**
046         * @see org.apache.james.jspf.executor.SPFExecutor#execute(org.apache.james.jspf.core.SPFSession, org.apache.james.jspf.executor.FutureSPFResult)
047         */
048        public void execute(SPFSession session, FutureSPFResult result) {
049            SPFChecker checker;
050            while ((checker = session.popChecker()) != null) {
051                // only execute checkers we added (better recursivity)
052                log.debug("Executing checker: " + checker);
053                try {
054                    DNSLookupContinuation cont = checker.checkSPF(session);
055                    // if the checker returns a continuation we return it
056                    while (cont != null) {
057                        DNSResponse response;
058                        try {
059                            response = new DNSResponse(dnsProbe.getRecords(cont
060                                    .getRequest()));
061                        } catch (TimeoutException e) {
062                            response = new DNSResponse(e);
063                        }
064                        cont = cont.getListener().onDNSResponse(response, session);
065                    }
066                } catch (Exception e) {
067                    while (e != null) {
068                        while (checker == null || !(checker instanceof SPFCheckerExceptionCatcher)) {
069                            checker = session.popChecker();
070                        }
071                        try {
072                            ((SPFCheckerExceptionCatcher) checker).onException(e, session);
073                            e = null;
074                        } catch (SPFResultException ex) {
075                            e = ex;
076                        } finally {
077                            checker = null;
078                        }
079                    }
080                }
081            }
082            result.setSPFResult(session);
083        }
084    
085    }