james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b...@apache.org
Subject svn commit: r453241 [1/2] - in /james/jspf/trunk/src/main/java/org/apache/james/jspf: ./ core/ localpolicy/ parser/ policies/ policies/local/ terms/
Date Thu, 05 Oct 2006 14:03:51 GMT
Author: bago
Date: Thu Oct  5 07:03:49 2006
New Revision: 453241

URL: http://svn.apache.org/viewvc?view=rev&rev=453241
Log:
Complete refactoring of SPF class: introduced the concept of Policy and NestedPolicy.
Now the SPF processing is based on a set (chain) of Policies. Basic behaviours have been added to the "policies" package and optional behaviours have been added to "policies.local" package.
SPF1Record now contains an iterator method that return a chained iterator over the terms.
SPF1Record now is able represents both a parsed record (previous record) or an unparsed spf record (String).

Added:
    james/jspf/trunk/src/main/java/org/apache/james/jspf/DefaultExplanationPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/AbstractNestedPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ChainPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/InitialChecksPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NestedPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NeutralIfNotMatchPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NoSPFRecordFoundPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ParseRecordPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/Policy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/SPFRetriever.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/BestGuessPolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/FallbackPolicy.java
      - copied, changed from r452836, james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/FallbackPolicy.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/OverridePolicy.java   (with props)
    james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/TrustedForwarderPolicy.java
      - copied, changed from r452845, james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/TrustedForwarderPolicy.java
Removed:
    james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/FallbackPolicy.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/TrustedForwarderPolicy.java
Modified:
    james/jspf/trunk/src/main/java/org/apache/james/jspf/SPF.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Directive.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Modifier.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Data.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Record.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPFChecker.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/parser/DefaultSPF1Parser.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/AMechanism.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExistsMechanism.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExpModifier.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/GenericModifier.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/IncludeMechanism.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/MXMechanism.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/RedirectModifier.java
    james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/UnknownModifier.java

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/DefaultExplanationPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/DefaultExplanationPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/DefaultExplanationPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/DefaultExplanationPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,83 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf;
+
+import org.apache.james.jspf.core.Logger;
+import org.apache.james.jspf.core.SPF1Constants;
+import org.apache.james.jspf.core.SPF1Data;
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.core.SPFChecker;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+import org.apache.james.jspf.macro.MacroExpand;
+import org.apache.james.jspf.policies.AbstractNestedPolicy;
+
+final class DefaultExplanationPolicy extends AbstractNestedPolicy {
+    /**
+     * 
+     */
+    private Logger log;
+    private String defExplanation;
+
+    /**
+     * @param spf
+     */
+    DefaultExplanationPolicy(Logger log, String explanation) {
+        this.log = log;
+        this.defExplanation = explanation;
+    }
+
+    protected SPF1Record getSPFRecordPostFilter(String currentDomain, SPF1Record spfRecord) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        // Default explanation policy
+        spfRecord.getModifiers().add(new SPFChecker() {
+            public void checkSPF(SPF1Data spfData) throws PermErrorException, NoneException, TempErrorException, NeutralException {
+                
+                if (SPF1Constants.FAIL.equals(spfData.getCurrentResult())) {  
+                    if (spfData.getExplanation()==null || spfData.getExplanation().equals("")) {
+                        String explanation;
+                        if (defExplanation == null) {
+                            explanation = SPF1Utils.DEFAULT_EXPLANATION;
+                        } else {
+                            explanation = defExplanation;
+                        }
+                        try {
+                            spfData.setExplanation(new MacroExpand(spfData, log)
+                                    .expandExplanation(SPF1Utils.DEFAULT_EXPLANATION));
+                        } catch (PermErrorException e) {
+                            // Should never happen !
+                            log.debug("Invalid defaulfExplanation: " + explanation);
+                        }
+                    }
+                }
+            }
+            
+            public String toString() {
+                if (defExplanation == null) {
+                    return "defaultExplanation";
+                } else {
+                    return "defaultExplanation="+defExplanation;
+                }
+            }
+        });
+        return spfRecord;
+    }
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/DefaultExplanationPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/SPF.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/SPF.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/SPF.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/SPF.java Thu Oct  5 07:03:49 2006
@@ -21,9 +21,7 @@
 package org.apache.james.jspf;
 
 import org.apache.james.jspf.core.DNSService;
-import org.apache.james.jspf.core.Directive;
 import org.apache.james.jspf.core.Logger;
-import org.apache.james.jspf.core.Modifier;
 import org.apache.james.jspf.core.SPF1Constants;
 import org.apache.james.jspf.core.SPF1Data;
 import org.apache.james.jspf.core.SPF1Record;
@@ -33,33 +31,46 @@
 import org.apache.james.jspf.exceptions.NoneException;
 import org.apache.james.jspf.exceptions.PermErrorException;
 import org.apache.james.jspf.exceptions.TempErrorException;
-import org.apache.james.jspf.localpolicy.FallbackPolicy;
-import org.apache.james.jspf.localpolicy.TrustedForwarderPolicy;
-import org.apache.james.jspf.macro.MacroExpand;
 import org.apache.james.jspf.parser.DefaultSPF1Parser;
 import org.apache.james.jspf.parser.DefaultTermsFactory;
+import org.apache.james.jspf.policies.ChainPolicy;
+import org.apache.james.jspf.policies.InitialChecksPolicy;
+import org.apache.james.jspf.policies.NeutralIfNotMatchPolicy;
+import org.apache.james.jspf.policies.NoSPFRecordFoundPolicy;
+import org.apache.james.jspf.policies.Policy;
+import org.apache.james.jspf.policies.ParseRecordPolicy;
+import org.apache.james.jspf.policies.SPFRetriever;
+import org.apache.james.jspf.policies.local.BestGuessPolicy;
+import org.apache.james.jspf.policies.local.FallbackPolicy;
+import org.apache.james.jspf.policies.local.TrustedForwarderPolicy;
 import org.apache.james.jspf.wiring.DNSServiceEnabled;
 import org.apache.james.jspf.wiring.LogEnabled;
 import org.apache.james.jspf.wiring.SPFCheckEnabled;
 import org.apache.james.jspf.wiring.WiringServiceTable;
 
+import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.List;
 
 /**
  * This class is used to generate a SPF-Test and provided all intressting data.
  */
-public class SPF implements SPFChecker {
+public class SPF implements SPFChecker, Policy {
 
-    private DNSService dnsProbe;
+    DNSService dnsProbe;
 
-    private SPFRecordParser parser;
+    public SPFRecordParser parser;
 
-    private Logger log;
+    Logger log;
     
-    private String defaultExplanation = null;
+    String defaultExplanation = null;
+    
+    /**
+     * The hostname to include
+     */
+    public static final String TRUSTED_FORWARDER_HOST = "spf.trusted-forwarder.org";
 
-    private boolean useBestGuess = false;
+
+    public boolean useBestGuess = false;
 
     private FallbackPolicy fallBack;
     
@@ -135,7 +146,8 @@
             // Setup the data
             spfData = new SPF1Data(mailFrom, hostName, ipAddress);
             spfData.enableDNSService(dnsProbe);
-            SPFInternalResult res = checkSPF(spfData);
+            checkSPF(spfData);
+            SPFInternalResult res = new SPFInternalResult(spfData.getCurrentResult(), spfData.getExplanation());
             resultChar = res.getResultChar();
             result = SPF1Utils.resultToName(resultChar);
             explanation = res.getExplanation();
@@ -165,157 +177,61 @@
         return ret;
 
     }
-
+    
     /**
      * @see org.apache.james.jspf.SPFChecker#checkSPF(org.apache.james.jspf.core.SPF1Data)
      */
-    public SPFInternalResult checkSPF(SPF1Data spfData) throws PermErrorException,
+    public void checkSPF(SPF1Data spfData) throws PermErrorException,
             NoneException, TempErrorException, NeutralException {
-        SPF1Record spfRecord = null;
-        spfData.setCurrentResult(SPF1Constants.NEUTRAL);
+
+        SPF1Record spfRecord = getSPFRecord(spfData.getCurrentDomain());
         
-        // Initial checks (spec 4.3)
-        if (spfData.getCurrentDomain() != null) {
-            String[] labels = spfData.getCurrentDomain().split("\\.");
-            for (int i = 0; i < labels.length; i++) {
-                if (labels[i] != null && labels[i].length() > 63) {
-                    throw new NoneException("Domain "+spfData.getCurrentDomain()+" is malformed (label longer than 63 characters)");
-                }
-            }
-        }
+        Iterator i = spfRecord.iterator();
+        while (i.hasNext()) {
+            SPFChecker m = (SPFChecker) i.next();
 
-        // Get the raw dns txt entry which contains a spf entry
-        String spfDnsEntry = getSpfRecord(dnsProbe,spfData.getCurrentDomain(),
-                SPF1Constants.SPF_VERSION);
-
-        // No SPF-Record found
-        if (spfDnsEntry == null) {
-            if (useBestGuess == true) {
-                // We should use bestguess
-                spfDnsEntry = SPF1Utils.BEST_GUESS_RECORD;
-                
-            } else if (fallBack != null && fallBack.getFallBackEntry(spfData.getCurrentDomain()) != null){
-                // We should use fallback
-                spfRecord = fallBack.getFallBackEntry(spfData.getCurrentDomain());
-                log.debug("Set FallBack SPF-Record:" +spfRecord.toString());
-            } else {
-                throw new NoneException("No SPF record found for host: " + spfData.getCurrentDomain());
-            }
-        }
+            m.checkSPF(spfData);
 
-        // check if the spfRecord was set before
-        if (spfRecord == null) {
-            spfRecord = parser.parse(spfDnsEntry);
         }
 
-        String qualifier = null;
-        boolean hasCommand = false;
-        Iterator com = null;
+        
+    }
 
-        // trustedForwarder support is enabled
-        if (useTrustedForwarder) {
-            com = new TrustedForwarderPolicy(spfRecord.getDirectives(),log).getUpdatedDirectives().iterator();
-        } else {
-        // get all commands
-            com = spfRecord.getDirectives().iterator();
-        }
-        while (com.hasNext()) {
+    /**
+     * @see org.apache.james.jspf.policies.Policy#getSPFRecord(java.lang.String)
+     */
+    public SPF1Record getSPFRecord(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
 
-            // if we reach maximum calls we must throw a PermErrorException. See
-            // SPF-RFC Section 10.1. Processing Limits
-            if (spfData.getCurrentDepth() > spfData.getMaxDepth()) {
-                throw new PermErrorException(
-                        "Maximum mechanism/modifier calls done: "
-                                + spfData.getCurrentDepth());
-            }
-
-            hasCommand = true;
-            Directive d = (Directive) com.next();
-
-            // logging
-            log.debug("Processing directive: " + d.getQualifier()
-                    + d.getMechanism().toString());
-
-            qualifier = d.run(spfData);
-
-            // logging
-            log.debug("Processed directive: " + d.getQualifier()
-                    + d.getMechanism().toString() + " returned " + qualifier);
-
-            if (qualifier != null) {
-                if (qualifier.equals("")) {
-                    spfData.setCurrentResult(SPF1Constants.PASS);
-                } else {
-                    spfData.setCurrentResult(qualifier);
-                }
-
-                spfData.setMatch(true);
-
-                // If we have a match we should break the while loop
-                break;
-            }
+        ArrayList policies = new ArrayList();
+        
+        policies.add(new SPFRetriever(dnsProbe));
+        
+        if (useBestGuess) {
+            policies.add(new BestGuessPolicy());
         }
-
-        Iterator mod = spfRecord.getModifiers().iterator();
-        while (mod.hasNext()) {
-            spfData.setCurrentDepth(spfData.getCurrentDepth() + 1);
-
-            // if we reach maximum calls we must throw a PermErrorException. See
-            // SPF-RFC Section 10.1. Processing Limits
-            if (spfData.getCurrentDepth() > spfData.getMaxDepth()) {
-                throw new PermErrorException(
-                        "Maximum mechanism/modifiers calls done: "
-                                + spfData.getCurrentDepth());
-            }
-
-            Modifier m = (Modifier) mod.next();
-
-            log.debug("Processing modifier: " + m.toString());
-
-            String q = m.run(spfData);
-
-            log.debug("Processed modifier: " + m.toString() + " resulted in "
-                    + q);
-
-            if (q != null) {
-                qualifier = q;
-            }
-
-            if (qualifier != null) {
-                spfData.setCurrentResult(qualifier);
-                spfData.setMatch(true);
-            }
+        
+        policies.add(new ParseRecordPolicy(parser));
+        
+        if (fallBack != null) {
+            policies.add(fallBack);
         }
 
-        // If no match was found set the result to neutral
-        if (!spfData.isMatch() && (hasCommand == true)) {
-            spfData.setCurrentResult(SPF1Constants.NEUTRAL);
-        } 
+        policies.add(new NoSPFRecordFoundPolicy());
         
-        if (SPF1Constants.FAIL.equals(spfData.getCurrentResult())) {  
-            if (spfData.getExplanation()==null || spfData.getExplanation().equals("")) {
-                if(defaultExplanation == null) {
-                    try {
-                        spfData.setExplanation(new MacroExpand(spfData, log)
-                                .expandExplanation(SPF1Utils.DEFAULT_EXPLANATION));
-                    } catch (PermErrorException e) {
-                        // Should never happen !
-                        log.debug("Invalid defaulfExplanation: " + SPF1Utils.DEFAULT_EXPLANATION);
-                    }
-                } else {
-                    try {
-                        spfData.setExplanation(new MacroExpand(spfData, log)
-                                .expandExplanation(defaultExplanation));
-                    } catch (PermErrorException e) {
-                        log.error("Invalid defaultExplanation: " + defaultExplanation);
-                    }
-                }
-            }
+        // trustedForwarder support is enabled
+        if (useTrustedForwarder) {
+            policies.add(new TrustedForwarderPolicy(log));
         }
+
+        policies.add(new NeutralIfNotMatchPolicy());
+
+        policies.add(new DefaultExplanationPolicy(log, defaultExplanation));
+        
+        policies.add(new InitialChecksPolicy());
         
-        return new SPFInternalResult(spfData.getCurrentResult(), spfData.getExplanation());
+        return new ChainPolicy(policies).getSPFRecord(currentDomain);
     }
-
+    
     /**
      * Set the amount of time (in seconds) before an TermError is returned when
      * the dnsserver not answer. Default is 20 seconds.
@@ -347,68 +263,6 @@
         this.useBestGuess  = useBestGuess;
     }
     
-
-    /**
-     * Get the SPF-Record for a server given it's version
-     * 
-     * TODO: support SPF Records too. This will be done if dnsjava support it!
-     * 
-     * @param dns
-     *            The dns service to query
-     * @param hostname
-     *            The hostname for which we want to retrieve the SPF-Record
-     * @param spfVersion
-     *            The SPF-Version which should used.
-     * @return The SPF-Record if one is found.
-     * @throws PermErrorException
-     *             if more then one SPF-Record was found.
-     * @throws TempErrorException
-     *             if the lookup result was "TRY_AGAIN"
-     */
-    public String getSpfRecord(DNSService dns, String hostname, String spfVersion)
-            throws PermErrorException, TempErrorException {
-
-        String returnValue = null;
-        try {
-            List spfR = dns.getRecords(hostname, DNSService.SPF);
-            if (spfR == null || spfR.isEmpty()) {
-                // do DNS lookup for TXT
-                spfR = dns.getRecords(hostname, DNSService.TXT);
-            }
-    
-            // process returned records
-            if (spfR != null && !spfR.isEmpty()) {
-    
-                Iterator all = spfR.iterator();
-    
-                while (all.hasNext()) {
-                    // DO NOT trim the result!
-                    String compare = all.next().toString();
-    
-                    // TODO is this correct? we remove the first and last char if the
-                    // result has an initial " 
-                    // remove '"'
-                    if (compare.charAt(0)=='"') {
-                        compare = compare.toLowerCase().substring(1,
-                                compare.length() - 1);
-                    }
-    
-                    // We trim the compare value only for the comparison
-                    if (compare.trim().startsWith(spfVersion + " ") || compare.trim().equals(spfVersion)) {
-                        if (returnValue == null) {
-                            returnValue = compare;
-                        } else {
-                            throw new PermErrorException(
-                                    "More than 1 SPF record found for host: " + hostname);
-                        }
-                    }
-                }
-            }
-            return returnValue;
-        } catch (DNSService.TimeoutException e) {
-            throw new TempErrorException("Timeout querying dns");
-        }
-    }
     
     /**
      * Return the FallbackPolicy object which can be used to 

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Directive.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Directive.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Directive.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Directive.java Thu Oct  5 07:03:49 2006
@@ -27,12 +27,14 @@
 /**
  * A Directive is a mechanism with a resulting qualifier.
  */
-public class Directive {
+public class Directive implements SPFChecker {
 
     protected String qualifier = "+";
 
     private Mechanism mechanism = null;
 
+    private Logger log;
+
     /**
      * Construct Directive
      * 
@@ -40,9 +42,10 @@
      * @param mechanism The Mechanism 
      * @throws PermErrorException Get thrown if a PermError should returned
      */
-    public Directive(String qualifier, Mechanism mechanism)
+    public Directive(String qualifier, Mechanism mechanism, Logger logger)
             throws PermErrorException {
         super();
+        this.log = logger;
         if (qualifier != null && qualifier.length() > 0) {
             this.qualifier = qualifier;
         }
@@ -61,12 +64,24 @@
      * @throws TempErrorException get thrown if a TempError should returned
      * @throws NoneException get thrown if a NoneException should returned;
      */
-    public String run(SPF1Data spfData) throws PermErrorException,
+    public void checkSPF(SPF1Data spfData) throws PermErrorException,
             TempErrorException, NoneException {
-        if (mechanism.run(spfData)) {
-            return qualifier;
-        } else {
-            return null;
+        // if already have a current result we don't run this
+        if (spfData.getCurrentResult() == null) {
+            log.debug("Processing directive: " + this);
+
+            if (mechanism.run(spfData)) {
+                if (qualifier != null) {
+                    if (qualifier.equals("")) {
+                        spfData.setCurrentResult(SPF1Constants.PASS);
+                    } else {
+                        spfData.setCurrentResult(qualifier);
+                    }
+                }
+                
+                log.debug("Processed directive matched: " + this + " returned " + spfData.getCurrentResult());
+            }
+
         }
     }
 

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Modifier.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Modifier.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Modifier.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/core/Modifier.java Thu Oct  5 07:03:49 2006
@@ -20,28 +20,11 @@
 
 package org.apache.james.jspf.core;
 
-import org.apache.james.jspf.exceptions.PermErrorException;
-import org.apache.james.jspf.exceptions.TempErrorException;
-
 /**
  * This Interface represent a modifier
  * 
  */
-public interface Modifier {
-
-    /**
-     * Run the mechanismn with the give SPF1Data
-     * 
-     * @param spfData
-     *            The SPF1Data we should use
-     * @return host The host we should redirect / include
-     * @throws PermErrorException
-     *             Get thrown if there are any errors in modifiers
-     * @throws TempErrorException
-     *             Get thrown if DNS problems detected
-     */
-    public String run(SPF1Data spfData) throws PermErrorException,
-            TempErrorException;
+public interface Modifier extends SPFChecker {
 
     /**
      * Return true if the Modifier is only allowed once 

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Data.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Data.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Data.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Data.java Thu Oct  5 07:03:49 2006
@@ -70,8 +70,6 @@
 
     private String currentResult = null;
 
-    private boolean match = false;
-    
     private boolean ignoreExplanation = false;
 
     private DNSService dnsProbe;
@@ -285,35 +283,19 @@
         }
         return receivingDomain;
     }
-
-    /**
-     * Get currentDepth 
-     * 
-     * @return currentDepth The currentDeph
-     */
-    public int getCurrentDepth() {
-        return currentDepth;
-    }
-
-    /**
-     * Set currentDepth which is just processed. This will called from
-     * modifiers/mechanismn
-     * 
-     * @param currentDepth
-     *            The currentDepth
-     */
-    public void setCurrentDepth(int currentDepth) {
-        this.currentDepth = currentDepth;
-    }
-
+    
     /**
-     * Get the maxDepth
+     * Increase the current depth:
      * 
-     * @return maxDepth The maximum mechanismn/modifier which are allowed to
-     *         proccessed
+     * if we reach maximum calls we must throw a PermErrorException. See
+     * SPF-RFC Section 10.1. Processing Limits
      */
-    public int getMaxDepth() {
-        return MAX_DEPTH;
+    public void increaseCurrentDepth() throws PermErrorException {
+        this.currentDepth++;
+        if (currentDepth > MAX_DEPTH)
+            throw new PermErrorException(
+                    "Maximum mechanism/modifiers calls done: "
+                        + currentDepth);
     }
 
     /**
@@ -361,25 +343,6 @@
      */
     public String getCurrentResult() {
         return currentResult;
-    }
-
-    /**
-     * Get set if an mechanismn or modifier match
-     * 
-     * @param match
-     *            true or flase
-     */
-    public void setMatch(boolean match) {
-        this.match = match;
-    }
-
-    /**
-     * Return true if a mechanismn or modifier matched
-     * 
-     * @return true or false
-     */
-    public boolean isMatch() {
-        return match;
     }
     
     /**

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Record.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Record.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Record.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPF1Record.java Thu Oct  5 07:03:49 2006
@@ -21,7 +21,8 @@
 package org.apache.james.jspf.core;
 
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * The Class represent the SPF1 Record and provide methods to get all directives
@@ -29,10 +30,20 @@
  * 
  */
 public class SPF1Record {
+    
+    private String record;
 
-    private Collection directives = new ArrayList();
+    public SPF1Record() {
+        this.record = null;
+    }
+    
+    public SPF1Record(String record) {
+        this.record = record;
+    }
+
+    private List directives = new ArrayList();
 
-    private Collection modifiers = new ArrayList();
+    private List modifiers = new ArrayList();
 
     /**
      * Return the directives as Collection
@@ -40,7 +51,7 @@
      * @return directives Collection of all qualifier+mechanism which should be
      *         used
      */
-    public Collection getDirectives() {
+    public List getDirectives() {
         return directives;
     }
 
@@ -49,8 +60,54 @@
      * 
      * @return modifiers Collection of all modifiers which should be used
      */
-    public Collection getModifiers() {
+    public List getModifiers() {
         return modifiers;
+    }
+
+    /**
+     * @return the record in its string source format
+     */
+    public String getRecord() {
+        return record;
+    }
+
+    /**
+     * @param record a record in its string source format
+     */
+    public void setRecord(String record) {
+        this.record = record;
+    }
+    
+    /**
+     * Return a single iterator over Directives and Modifiers
+     * 
+     * @return a chained iterator of the terms
+     */
+    public Iterator iterator() {
+        return new Iterator() {
+            boolean first = true;
+            Iterator current = getDirectives().iterator();
+
+            public boolean hasNext() {
+                if (current.hasNext()) { 
+                    return true;
+                } else if (first) {
+                    current = getModifiers().iterator();
+                    first = false;
+                    return current.hasNext();
+                } else return false;
+            }
+
+            public Object next() {
+                current.hasNext();
+                return current.next();
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException("Readonly iterator");
+            }
+            
+        };
     }
 
 }

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPFChecker.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPFChecker.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPFChecker.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/core/SPFChecker.java Thu Oct  5 07:03:49 2006
@@ -19,7 +19,6 @@
 
 package org.apache.james.jspf.core;
 
-import org.apache.james.jspf.SPFInternalResult;
 import org.apache.james.jspf.exceptions.NeutralException;
 import org.apache.james.jspf.exceptions.NoneException;
 import org.apache.james.jspf.exceptions.PermErrorException;
@@ -35,8 +34,6 @@
      * 
      * @param spfData
      *             The SPF1Data which should be used to run the check
-     * @return result 
-     *             The SPFInternalResult 
      * @throws PermErrorException
      *             Get thrown if an error was detected
      * @throws NoneException
@@ -46,7 +43,7 @@
      * @throws NeutralException  
      *             Get thrown if the result should be neutral
      */
-    public SPFInternalResult checkSPF(SPF1Data spfData)
+    public void checkSPF(SPF1Data spfData)
             throws PermErrorException, NoneException, TempErrorException,
             NeutralException;
 

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/parser/DefaultSPF1Parser.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/parser/DefaultSPF1Parser.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/parser/DefaultSPF1Parser.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/parser/DefaultSPF1Parser.java Thu Oct  5 07:03:49 2006
@@ -247,7 +247,7 @@
         return modifierRegex.toString();
     }
 
-    /* (non-Javadoc)
+    /**
      * @see org.apache.james.jspf.parser.SPFRecordParser#parse(java.lang.String)
      */
     public SPF1Record parse(String spfRecord) throws PermErrorException,
@@ -310,7 +310,7 @@
                             TERM_STEP_REGEX_MECHANISM_POS);
 
                     result.getDirectives().add(
-                            new Directive(qualifier, (Mechanism) mech));
+                            new Directive(qualifier, (Mechanism) mech, log));
 
                 }
 

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/AbstractNestedPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/AbstractNestedPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/AbstractNestedPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/AbstractNestedPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,64 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+
+public abstract class AbstractNestedPolicy implements NestedPolicy, Policy {
+
+    private Policy childPolicy;
+
+    public void setChildPolicy(Policy children) {
+        if (children == null) {
+            throw new IllegalStateException("This policy needs a valid child policy: "+this.getClass().toString());
+        }
+        this.childPolicy = children;
+    }
+    
+    public SPF1Record getSPFRecord(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        SPF1Record res = getSPFRecordOverride(currentDomain);
+        if (res == null && childPolicy != null) {
+            res = childPolicy.getSPFRecord(currentDomain);
+            if (res == null) {
+                res = getSPFRecordFallback(currentDomain);
+            } else {
+                res = getSPFRecordPostFilter(currentDomain, res);
+            }
+        }
+        return res;
+    }
+
+    protected SPF1Record getSPFRecordPostFilter(String currentDomain, SPF1Record res) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        return res;
+    }
+
+    protected SPF1Record getSPFRecordFallback(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        return null;
+    }
+
+    protected SPF1Record getSPFRecordOverride(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        return null;
+    }
+    
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/AbstractNestedPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ChainPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ChainPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ChainPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ChainPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,64 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Composed policy: get a list of NestedPolicies and chain them
+ * in a single policy
+ */
+public class ChainPolicy implements Policy {
+    
+    private Policy policy;
+
+    /**
+     * Create a new ChainPolicy
+     * @param policies an array of Polcy and NestedPolicy objects
+     */
+    public ChainPolicy(List policies) {
+        policy = null;
+        Iterator i = policies.iterator();
+        while (i.hasNext()) {
+            Policy newP = (Policy) i.next();
+            if (newP instanceof NestedPolicy) {
+                ((NestedPolicy) newP).setChildPolicy(policy);
+            }
+            policy = newP;
+        }
+    }
+    
+    /**
+     * @see org.apache.james.jspf.policies.Policy#getSPFRecord(java.lang.String)
+     */
+    public SPF1Record getSPFRecord(String currentDomain)
+            throws PermErrorException, TempErrorException, NoneException,
+            NeutralException {
+        return policy.getSPFRecord(currentDomain);
+    }
+
+}

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ChainPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/InitialChecksPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/InitialChecksPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/InitialChecksPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/InitialChecksPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,50 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+
+/**
+ * Run the checks on the validity of the domain
+ * This is an override filter to be executed as the first 
+ * so it should be added as the last filter.
+ */
+public final class InitialChecksPolicy extends AbstractNestedPolicy {
+    
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordOverride(java.lang.String)
+     */
+    protected SPF1Record getSPFRecordOverride(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        // Initial checks (spec 4.3)
+        if (currentDomain != null) {
+            String[] labels = currentDomain.split("\\.");
+            for (int i = 0; i < labels.length; i++) {
+                if (labels[i] != null && labels[i].length() > 63) {
+                    throw new NoneException("Domain "+currentDomain+" is malformed (label longer than 63 characters)");
+                }
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/InitialChecksPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NestedPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NestedPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NestedPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NestedPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,31 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+/**
+ * Interface used to set the next policy in the chain
+ */
+public interface NestedPolicy {
+    /**
+     * Set a new children for this Policy
+     * @param children the children policy
+     */
+    public void setChildPolicy(Policy children);
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NestedPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NeutralIfNotMatchPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NeutralIfNotMatchPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NeutralIfNotMatchPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NeutralIfNotMatchPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,58 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+import org.apache.james.jspf.core.SPF1Constants;
+import org.apache.james.jspf.core.SPF1Data;
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.core.SPFChecker;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+
+/**
+ * Sets the result to NEUTRAL if no directive is found 
+ */
+public class NeutralIfNotMatchPolicy extends AbstractNestedPolicy {
+    
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordPostFilter(java.lang.String, org.apache.james.jspf.core.SPF1Record)
+     */
+    protected SPF1Record getSPFRecordPostFilter(String currentDomain, SPF1Record spfRecord) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        // Set the result to NEUTRAL if at least a directive is present and it didn't match
+        // Maybe we should simply append a "?all" at the end, as modifier
+        if (spfRecord.getDirectives().size() > 0) {
+            spfRecord.getModifiers().add(new SPFChecker() {
+                public void checkSPF(SPF1Data spfData) throws PermErrorException, NoneException, TempErrorException, NeutralException {
+                    // If no match was found set the result to neutral
+                    if (spfData.getCurrentResult() == null) {
+                        spfData.setCurrentResult(SPF1Constants.NEUTRAL);
+                    }
+                }
+                
+                public String toString() {
+                    return "defaultresult";
+                }
+            });
+        }
+        return spfRecord;
+    }
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NeutralIfNotMatchPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NoSPFRecordFoundPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NoSPFRecordFoundPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NoSPFRecordFoundPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NoSPFRecordFoundPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,38 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+
+/**
+ * Throws a NoneException if no record has been found
+ */
+public class NoSPFRecordFoundPolicy extends AbstractNestedPolicy {
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordFallback(java.lang.String)
+     */
+    protected SPF1Record getSPFRecordFallback(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        throw new NoneException("No SPF record found for host: " + currentDomain);
+    }
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/NoSPFRecordFoundPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ParseRecordPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ParseRecordPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ParseRecordPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ParseRecordPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,46 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.core.SPFRecordParser;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+
+/**
+ * Parse the record
+ */
+public class ParseRecordPolicy extends AbstractNestedPolicy {
+
+    private SPFRecordParser parser;
+
+    public ParseRecordPolicy(SPFRecordParser parser) {
+        this.parser = parser;
+    }
+
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordPostFilter(java.lang.String, org.apache.james.jspf.core.SPF1Record)
+     */
+    protected SPF1Record getSPFRecordPostFilter(String currentDomain, SPF1Record spfRecord) throws PermErrorException, NoneException, NeutralException {
+        // parse the record
+        return parser.parse(spfRecord.getRecord());
+    }
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/ParseRecordPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/Policy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/Policy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/Policy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/Policy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,48 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies;
+
+
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+
+/**
+ * Return an spf record from a given domain. 
+ */
+public interface Policy {
+
+    /**
+     * Get a record for the given domain
+     * 
+     * @param currentDomain the domain to retrieve the SPFRecord for
+     * @return the SPFRecord found
+     * @throws PermErrorException exception
+     * @throws TempErrorException exception
+     * @throws NoneException exception
+     * @throws NeutralException exception
+     */
+    public SPF1Record getSPFRecord(String currentDomain)
+            throws PermErrorException, TempErrorException, NoneException,
+            NeutralException;
+
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/Policy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/SPFRetriever.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/SPFRetriever.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/SPFRetriever.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/SPFRetriever.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,119 @@
+package org.apache.james.jspf.policies;
+
+import org.apache.james.jspf.core.DNSService;
+import org.apache.james.jspf.core.SPF1Constants;
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Get the raw dns txt entry which contains a spf entry
+ */
+public class SPFRetriever extends AbstractNestedPolicy {
+    /**
+     * dns service
+     */
+    private final DNSService dns;
+
+
+    /**
+     * A new instance of the SPFRetriever
+     * 
+     * @param dns the dns service
+     */
+    public SPFRetriever(DNSService dns) {
+        this.dns = dns;
+    }
+
+
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#setChildPolicy(org.apache.james.jspf.policies.Policy)
+     */
+    public void setChildPolicy(Policy children) {
+        if (children != null) {
+            throw new IllegalStateException("Cannot set a child policy for SPFRetriever");
+        }
+    }
+
+
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordOverride(java.lang.String)
+     */
+    protected SPF1Record getSPFRecordOverride(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        // retrieve the SPFRecord
+        String spfDnsEntry = retrieveSpfRecord(currentDomain);
+        if (spfDnsEntry != null) {
+            return new SPF1Record(spfDnsEntry);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Get the SPF-Record for a server given it's version
+     * 
+     * TODO: support SPF Records too. This will be done if dnsjava support it!
+     * 
+     * @param dns
+     *            The dns service to query
+     * @param hostname
+     *            The hostname for which we want to retrieve the SPF-Record
+     * @param spfVersion
+     *            The SPF-Version which should used.
+     * @return The SPF-Record if one is found.
+     * @throws PermErrorException
+     *             if more then one SPF-Record was found.
+     * @throws TempErrorException
+     *             if the lookup result was "TRY_AGAIN"
+     */
+    private String retrieveSpfRecord(String hostname)
+            throws PermErrorException, TempErrorException {
+
+        String returnValue = null;
+        try {
+            List spfR = dns.getRecords(hostname, DNSService.SPF);
+            if (spfR == null || spfR.isEmpty()) {
+                // do DNS lookup for TXT
+                spfR = dns.getRecords(hostname, DNSService.TXT);
+            }
+    
+            // process returned records
+            if (spfR != null && !spfR.isEmpty()) {
+    
+                Iterator all = spfR.iterator();
+    
+                while (all.hasNext()) {
+                    // DO NOT trim the result!
+                    String compare = all.next().toString();
+    
+                    // TODO is this correct? we remove the first and last char if the
+                    // result has an initial " 
+                    // remove '"'
+                    if (compare.charAt(0)=='"') {
+                        compare = compare.toLowerCase().substring(1,
+                                compare.length() - 1);
+                    }
+    
+                    // We trim the compare value only for the comparison
+                    if (compare.trim().startsWith(SPF1Constants.SPF_VERSION + " ") || compare.trim().equals(SPF1Constants.SPF_VERSION)) {
+                        if (returnValue == null) {
+                            returnValue = compare;
+                        } else {
+                            throw new PermErrorException(
+                                    "More than 1 SPF record found for host: " + hostname);
+                        }
+                    }
+                }
+            }
+            return returnValue;
+        } catch (DNSService.TimeoutException e) {
+            throw new TempErrorException("Timeout querying dns");
+        }
+    }
+
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/SPFRetriever.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/BestGuessPolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/BestGuessPolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/BestGuessPolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/BestGuessPolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,36 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies.local;
+
+import org.apache.james.jspf.SPF1Utils;
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
+import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+import org.apache.james.jspf.policies.AbstractNestedPolicy;
+
+public class BestGuessPolicy extends AbstractNestedPolicy {
+
+    protected SPF1Record getSPFRecordFallback(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        // We should use bestguess
+        return new SPF1Record(SPF1Utils.BEST_GUESS_RECORD);
+    }
+}
\ No newline at end of file

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/BestGuessPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/FallbackPolicy.java (from r452836, james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/FallbackPolicy.java)
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/FallbackPolicy.java?view=diff&rev=453241&p1=james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/FallbackPolicy.java&r1=452836&p2=james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/FallbackPolicy.java&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/FallbackPolicy.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/FallbackPolicy.java Thu Oct  5 07:03:49 2006
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.jspf.localpolicy;
+package org.apache.james.jspf.policies.local;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -30,11 +30,12 @@
 import org.apache.james.jspf.exceptions.NeutralException;
 import org.apache.james.jspf.exceptions.NoneException;
 import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.policies.AbstractNestedPolicy;
 
 /**
  * Class to support Fallback feature
  */
-public class FallbackPolicy {
+public class FallbackPolicy extends AbstractNestedPolicy {
 
     private Map fallBackMap;
 
@@ -42,7 +43,7 @@
 
     private Logger log;
 
-    public FallbackPolicy(Logger log, SPFRecordParser parser){
+    public FallbackPolicy(Logger log, SPFRecordParser parser) {
         this.log = log;
         fallBackMap = Collections.synchronizedMap(new HashMap());
         this.parser = parser;
@@ -116,6 +117,13 @@
     }
 
     /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordFallback(java.lang.String)
+     */
+    public SPF1Record getSPFRecordFallback(String host) {
+        return getMySPFRecord(host);
+    }
+    
+    /**
      * Return the SPF1Record for the given host
      * 
      * @param host
@@ -123,7 +131,7 @@
      * @return the SPF1Record of null if no SPF1Record was found in fallback for
      *         the given host
      */
-    public SPF1Record getFallBackEntry(String host) {
+    protected SPF1Record getMySPFRecord(String host) {
         Object fallBack = null;
 
         synchronized (fallBackMap) {
@@ -159,4 +167,5 @@
         }
         return null;
     }
+
 }

Added: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/OverridePolicy.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/OverridePolicy.java?view=auto&rev=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/OverridePolicy.java (added)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/OverridePolicy.java Thu Oct  5 07:03:49 2006
@@ -0,0 +1,48 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.jspf.policies.local;
+
+import org.apache.james.jspf.core.Logger;
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.core.SPFRecordParser;
+
+public class OverridePolicy extends FallbackPolicy {
+
+    public OverridePolicy(Logger log, SPFRecordParser parser) {
+        super(log, parser);
+    }
+    
+
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordFallback(java.lang.String)
+     */
+    public SPF1Record getSPFRecordFallback(String host) {
+        return null;
+    }
+
+
+    /**
+     * @see org.apache.james.jspf.policies.AbstractNestedPolicy#getSPFRecordFallback(java.lang.String)
+     */
+    public SPF1Record getSPFRecordOverride(String host) {
+        return getMySPFRecord(host);
+    }
+
+}

Propchange: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/OverridePolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/TrustedForwarderPolicy.java (from r452845, james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/TrustedForwarderPolicy.java)
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/TrustedForwarderPolicy.java?view=diff&rev=453241&p1=james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/TrustedForwarderPolicy.java&r1=452845&p2=james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/TrustedForwarderPolicy.java&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/localpolicy/TrustedForwarderPolicy.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/policies/local/TrustedForwarderPolicy.java Thu Oct  5 07:03:49 2006
@@ -17,82 +17,51 @@
  * under the License.                                           *
  ****************************************************************/
 
+package org.apache.james.jspf.policies.local;
 
-
-package org.apache.james.jspf.localpolicy;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
+import org.apache.james.jspf.SPF;
 import org.apache.james.jspf.core.Directive;
-import org.apache.james.jspf.core.Mechanism;
+import org.apache.james.jspf.core.Logger;
+import org.apache.james.jspf.core.SPF1Record;
+import org.apache.james.jspf.exceptions.NeutralException;
+import org.apache.james.jspf.exceptions.NoneException;
 import org.apache.james.jspf.exceptions.PermErrorException;
+import org.apache.james.jspf.exceptions.TempErrorException;
+import org.apache.james.jspf.policies.AbstractNestedPolicy;
 import org.apache.james.jspf.terms.IncludeMechanism;
-import org.apache.james.jspf.core.Logger;
 
-/**
- * 
- * This class represent a local policy to support the whitelist of trusted-forwarder.org
- */
-public class TrustedForwarderPolicy {
+public class TrustedForwarderPolicy extends AbstractNestedPolicy {
 
-    /**
-     * The hostname to include
-     */
-    private static final String TRUSTED_FORWARDER_HOST = "spf.trusted-forwarder.org";
-    
-    /**
-     * The ArrayList whill holds the Directives to return
-     */
-    private ArrayList aCom;
-    
-    /**
-     * The logger
-     */
     private Logger log;
-    
+
     /**
-     * Default Constructor 
-     * 
-     * @param directives the Collection which holds all directives
-     * @parm log the logger the logger
-     * @throws IllegalArgumentException get thrown if the given Collection is null
+     * @param spf
      */
-    public TrustedForwarderPolicy (Collection directives,Logger log)throws IllegalArgumentException {
-        if (directives == null) throw new IllegalArgumentException("Passed Collection is null");
-        this.aCom = new ArrayList(directives);
+    public TrustedForwarderPolicy(Logger log) {
         this.log = log;
     }
 
-    /**
-     * Return an updated Collection which hold now a new include mechanism to quere trusted-forwarder.org. The
-     * Collection get only updated if the last mechanism is -all or ?all. If not the original Collection is returned
-     * 
-     * @return aCom a Collection which holds the directives
-     */
-    public Collection getUpdatedDirectives() {
-        String mechanism = ((Directive) aCom.get(aCom.size())).toString().toLowerCase();
+    protected SPF1Record getSPFRecordPostFilter(String currentDomain, SPF1Record spfRecord) throws PermErrorException, TempErrorException, NoneException, NeutralException {
+        String mechanism = ((Directive) spfRecord.getDirectives().get(spfRecord.getDirectives().size())).toString();
         if (mechanism.equals("-all") || mechanism.equals("?all")) {
-            log.debug("Add TrustedForwarderPolicy = include:"+TRUSTED_FORWARDER_HOST);
+            log.debug("Add TrustedForwarderPolicy = include:"+SPF.TRUSTED_FORWARDER_HOST);
             try {
-                Mechanism trusted = new IncludeMechanism() {
+                IncludeMechanism trusted = new IncludeMechanism() {
                     /**
                      * Set the host to use 
                      * 
                      * @param host the host to include
                      */
-                    public Mechanism setHost(String host) {
+                    public synchronized IncludeMechanism setHost(String host) {
                         this.host = host;
                         return this;
                     }
-                }.setHost(TRUSTED_FORWARDER_HOST);
-                aCom.add(aCom.size()-1, new Directive(null,trusted));
+                }.setHost(SPF.TRUSTED_FORWARDER_HOST);
+                spfRecord.getDirectives().add(spfRecord.getDirectives().size()-1, new Directive(null, trusted, log));
             } catch (PermErrorException e) {
                 // will never happen
             }
-            return aCom;
-        } else {
-            return aCom;
         }
+        return spfRecord;
     }
-}
+}
\ No newline at end of file

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/AMechanism.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/AMechanism.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/AMechanism.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/AMechanism.java Thu Oct  5 07:03:49 2006
@@ -59,7 +59,7 @@
     public boolean run(SPF1Data spfData) throws PermErrorException,
             TempErrorException {
         // update currentDepth
-        spfData.setCurrentDepth(spfData.getCurrentDepth() + 1);
+        spfData.increaseCurrentDepth();
 
         // Get the right host.
         String host = expandHost(spfData);

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExistsMechanism.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExistsMechanism.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExistsMechanism.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExistsMechanism.java Thu Oct  5 07:03:49 2006
@@ -53,7 +53,7 @@
         List aRecords;
 
         // update currentDepth
-        spfData.setCurrentDepth(spfData.getCurrentDepth() + 1);
+        spfData.increaseCurrentDepth();
 
         String host = expandHost(spfData);
 

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExpModifier.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExpModifier.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExpModifier.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/ExpModifier.java Thu Oct  5 07:03:49 2006
@@ -21,7 +21,6 @@
 package org.apache.james.jspf.terms;
 
 import org.apache.james.jspf.core.DNSService;
-import org.apache.james.jspf.core.Logger;
 import org.apache.james.jspf.core.SPF1Constants;
 import org.apache.james.jspf.core.SPF1Data;
 import org.apache.james.jspf.exceptions.PermErrorException;
@@ -29,7 +28,6 @@
 import org.apache.james.jspf.macro.MacroExpand;
 import org.apache.james.jspf.util.SPFTermsRegexps;
 import org.apache.james.jspf.wiring.DNSServiceEnabled;
-import org.apache.james.jspf.wiring.LogEnabled;
 
 import java.util.List;
 
@@ -37,7 +35,7 @@
  * This class represent the exp modifier
  * 
  */
-public class ExpModifier extends GenericModifier implements LogEnabled, DNSServiceEnabled {
+public class ExpModifier extends GenericModifier implements DNSServiceEnabled {
 
     /**
      * ABNF: explanation = "exp" "=" domain-spec
@@ -45,8 +43,6 @@
     public static final String REGEX = "[eE][xX][pP]" + "\\="
             + SPFTermsRegexps.DOMAIN_SPEC_REGEX;
 
-    private Logger log;
-
     private DNSService dnsService;
 
     /**
@@ -55,20 +51,19 @@
      * 
      * @param spfData
      *            The SPF1Data which should used
-     * 
      */
-    public String run(SPF1Data spfData) {
+    protected void checkSPFLogged(SPF1Data spfData) {
         String exp = null;
         String host = getHost();
 
+        // If we should ignore the explanation we don't have to run this class
+        if (spfData.ignoreExplanation() == true)
+            return;
+        
         // If the currentResult is not fail we have no need to run all these
         // methods!
         if (spfData.getCurrentResult()== null || !spfData.getCurrentResult().equals(SPF1Constants.FAIL))
-            return null;
-        
-        // If we should ignore the explanation we don't have to run this class
-        if (spfData.ignoreExplanation() == true)
-            return null;
+            return;
 
         try {
             host = new MacroExpand(spfData, log).expandDomain(host);
@@ -76,7 +71,7 @@
                 exp = getTxtCatType(dnsService, host);
             } catch (TempErrorException e) {
                 // Nothing todo here.. just return null
-                return null;
+                return;
             }
 
             if ((exp != null) && (!exp.equals(""))) {
@@ -85,23 +80,9 @@
             } 
         } catch (PermErrorException e) {
             // Only catch the error and return null
-            return null;
+            return;
         }
-        return null;
-    }
-
-    /**
-     * @see org.apache.james.jspf.core.Modifier#enforceSingleInstance()
-     */
-    public boolean enforceSingleInstance() {
-        return true;
-    }
-
-    /**
-     * @see org.apache.james.jspf.wiring.LogEnabled#enableLogging(org.apache.james.jspf.core.Logger)
-     */
-    public void enableLogging(Logger logger) {
-        this.log = logger;
+        return;
     }
 
 

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/GenericModifier.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/GenericModifier.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/GenericModifier.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/GenericModifier.java Thu Oct  5 07:03:49 2006
@@ -22,25 +22,45 @@
 
 import org.apache.james.jspf.core.Configurable;
 import org.apache.james.jspf.core.Configuration;
+import org.apache.james.jspf.core.Logger;
 import org.apache.james.jspf.core.Modifier;
 import org.apache.james.jspf.core.SPF1Data;
 import org.apache.james.jspf.exceptions.PermErrorException;
 import org.apache.james.jspf.exceptions.TempErrorException;
+import org.apache.james.jspf.wiring.LogEnabled;
 
 /**
  * This abstract class represent a gerneric modifier
  * 
  */
-public abstract class GenericModifier implements Modifier, Configurable {
+public abstract class GenericModifier implements Modifier, Configurable, LogEnabled {
 
     private String host;
 
+    protected Logger log;
+
     /**
      * @see org.apache.james.jspf.core.Modifier#run(SPF1Data)
      * 
      */
-    public abstract String run(SPF1Data spfData) throws PermErrorException,
-            TempErrorException;
+    public void checkSPF(SPF1Data spfData) throws PermErrorException,
+            TempErrorException {
+        log.debug("Processing modifier: " + this);
+        checkSPFLogged(spfData);
+        log.debug("Processed modifier: " + this + " resulted in "
+                + spfData.getCurrentResult());
+    }
+    
+    protected abstract void checkSPFLogged(SPF1Data spfData) throws PermErrorException,
+        TempErrorException;
+
+
+    /**
+     * @see org.apache.james.jspf.core.Modifier#enforceSingleInstance()
+     */
+    public boolean enforceSingleInstance() {
+        return true;
+    }
 
     /**
      * @see org.apache.james.jspf.core.Configurable#config(Configuration)
@@ -57,5 +77,14 @@
     protected synchronized String getHost() {
         return host;
     }
+    
+
+    /**
+     * @see org.apache.james.jspf.wiring.LogEnabled#enableLogging(org.apache.james.jspf.core.Logger)
+     */
+    public void enableLogging(Logger logger) {
+        this.log = logger;
+    }
+
 
 }

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/IncludeMechanism.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/IncludeMechanism.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/IncludeMechanism.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/IncludeMechanism.java Thu Oct  5 07:03:49 2006
@@ -69,7 +69,7 @@
         String host = getHost();
 
         // update currentDepth
-        spfData.setCurrentDepth(spfData.getCurrentDepth() + 1);      
+        spfData.increaseCurrentDepth();      
         
         // throws a PermErrorException that we can pass through
         host = new MacroExpand(spfData, log).expandDomain(host);
@@ -83,12 +83,11 @@
             
             // On includes we should not use the explanation of the included domain
             spfData.setIgnoreExplanation(true);
+            // set a null current result
+            spfData.setCurrentResult(null);
             
-    
-            
-            String res = null;
             try {
-                 res = spfChecker.checkSPF(spfData).getResultChar();
+                 spfChecker.checkSPF(spfData);
               
             } catch (NoneException e) {
                 throw new PermErrorException("included checkSPF returned NoneException");
@@ -96,19 +95,18 @@
                 throw new PermErrorException("included checkSPF returned NeutralException");
             }
             
-            // Reset the ignore
-            spfData.setIgnoreExplanation(false);
-            
-            if (res == null) {
+            if (spfData.getCurrentResult() == null) {
                 throw new TempErrorException("included checkSPF returned null");
-            } else if (res.equals(SPF1Constants.PASS)) {
+            } else if (spfData.getCurrentResult().equals(SPF1Constants.PASS)) {
                 return true;
-            } else if (res.equals(SPF1Constants.FAIL) || res.equals(SPF1Constants.SOFTFAIL) || res.equals(SPF1Constants.NEUTRAL)) {
+            } else if (spfData.getCurrentResult().equals(SPF1Constants.FAIL) || spfData.getCurrentResult().equals(SPF1Constants.SOFTFAIL) || spfData.getCurrentResult().equals(SPF1Constants.NEUTRAL)) {
                 return false;
             } else {
                 throw new TempErrorException("included checkSPF returned an Illegal result");
             }
         } finally {
+            // Reset the ignore
+            spfData.setIgnoreExplanation(false);
             spfData.setCurrentDomain(prevHost);
             spfData.setCurrentResult(prevRes);
         }

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/MXMechanism.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/MXMechanism.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/MXMechanism.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/MXMechanism.java Thu Oct  5 07:03:49 2006
@@ -54,7 +54,7 @@
         IPAddr checkAddress;
 
         // update currentDepth
-        spfData.setCurrentDepth(spfData.getCurrentDepth() + 1);
+        spfData.increaseCurrentDepth();
 
         // Get the right host.
         String host = expandHost(spfData);

Modified: james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java
URL: http://svn.apache.org/viewvc/james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java?view=diff&rev=453241&r1=453240&r2=453241
==============================================================================
--- james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java (original)
+++ james/jspf/trunk/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java Thu Oct  5 07:03:49 2006
@@ -54,7 +54,7 @@
         ArrayList validatedHosts = new ArrayList();
 
         // update currentDepth
-        spfData.setCurrentDepth(spfData.getCurrentDepth() + 1);
+        spfData.increaseCurrentDepth();
 
         // Get the right host.
         String host = expandHost(spfData);



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message