You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by ga...@apache.org on 2006/07/23 07:45:44 UTC

svn commit: r424677 - in /incubator/roller/branches/roller_3.0: src/org/apache/roller/config/PingConfig.java src/org/apache/roller/ui/core/RollerContext.java src/org/apache/roller/ui/core/pings/WeblogUpdatePinger.java web/WEB-INF/classes/roller.properties

Author: gangolli
Date: Sat Jul 22 22:45:43 2006
New Revision: 424677

URL: http://svn.apache.org/viewvc?rev=424677&view=rev
Log:
Fix/improvements for ROL-1192 onto roller_3.0 branch. Introduce statically configurable mechanism for interoperating with buggy WeblogUpdates.ping variants.  Implement "noname" ping variant (which omits the name parameter from the ping) in order to support pings to IceRocket.   Be resilient to responses of the wrong type (also for IceRocket).  Add IceRocket to default initial common targets.

Modified:
    incubator/roller/branches/roller_3.0/src/org/apache/roller/config/PingConfig.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/RollerContext.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/pings/WeblogUpdatePinger.java
    incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/config/PingConfig.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/config/PingConfig.java?rev=424677&r1=424676&r2=424677&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/config/PingConfig.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/config/PingConfig.java Sat Jul 22 22:45:43 2006
@@ -25,6 +25,7 @@
 import org.apache.roller.model.RollerFactory;
 import org.apache.roller.pojos.PingTargetData;
 
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -42,10 +43,6 @@
     private static final Log logger = LogFactory.getLog(PingConfig.class);
 
 
-    // Inhibit construction
-    private PingConfig() {
-    }
-
     // Config property for maximim ping attempts.
     static final String MAX_PING_ATTEMPTS_PROP = "pings.maxPingAttempts";
     private static final int MAX_PING_ATTEMPTS_DEFAULT = 3;
@@ -89,6 +86,24 @@
     // commenting out this property in the config file.
     private static final String PINGS_INITIAL_COMMON_TARGETS_PROP = "pings.initialCommonTargets";
 
+
+    // PingConfig property determining the known WeblogUpdates.ping variants/bugs
+    // in popular ping targets, which we are used when invoking pings on those targets.
+    // The value takes the form of a comma separated list of ping target urls and
+    // variant options, where each one is in the form {{pingurl}{option[[,option]...]}}.
+    private static final String PINGS_VARIANT_OPTIONS_PROP = "pings.variantOptions";
+    // Map of configured ping variants.  Maps a ping target hostname to a set of
+    // Strings representing variant options to be used when pinging this target.
+    // This was introduced in order to support certain buggy (but popular) ping
+    // targets that implement minor variants of the WeblogUpdates.ping call.
+    // This is initialized once at startup, and referenced when pings are made.
+    private static final Map configuredVariants = new HashMap();
+
+
+    // Inhibit construction
+    private PingConfig() {
+    }
+
     /**
      * Get the maximum number of ping attempts that should be made for each ping queue entry before we give up. If we
      * get apparently transient failures while trying to perform the ping, the entry is requeued for processing on later
@@ -152,8 +167,10 @@
         return RollerRuntimeConfig.getBooleanProperty(PINGS_SUSPEND_PING_PROCESSING_PROP);
     }
 
+    // Pattern used to parse common ping targets as well as ping variants.
     // Each initial commmon ping target is specified in the format {{name}{url}}
-    private static final Pattern PING_TARGET_SPEC = Pattern.compile("\\{\\{(.*?)\\}\\{(.*?)\\}\\}");
+    // Ping variants are also specified in a nested brace format {{url}{options}}
+    private static final Pattern NESTED_BRACE_PAIR = Pattern.compile("\\{\\{(.*?)\\}\\{(.*?)\\}\\}");
 
     /**
      * Initialize the common ping targets from the configuration properties. If the current list of common ping targets
@@ -163,7 +180,7 @@
      * Note: this is expected to be called during initialization  with transaction demarcation being handled by the
      * caller.
      *
-     * @see org.apache.roller.presentation.RollerContext#contextInitialized(javax.servlet.ServletContextEvent)
+     * @see org.apache.roller.ui.core.RollerContext#contextInitialized(javax.servlet.ServletContextEvent)
      */
     public static void initializeCommonTargets() throws RollerException {
         String configuredVal = RollerConfig.getProperty(PINGS_INITIAL_COMMON_TARGETS_PROP);
@@ -188,17 +205,70 @@
             // skip empty ones
             if (thisTarget.length() == 0) continue;
             // parse the ith target and store it
-            Matcher m = PING_TARGET_SPEC.matcher(configuredTargets[i].trim());
+            Matcher m = NESTED_BRACE_PAIR.matcher(thisTarget);
             if (m.matches() && m.groupCount() == 2) {
-                String name = m.group(1);
-                String url = m.group(2);
+                String name = m.group(1).trim();
+                String url = m.group(2).trim();
                 logger.info("Creating common ping target '" + name + "' from configuration properties.");
                 PingTargetData pingTarget = new PingTargetData(null, name, url, null, false);
                 pingTargetMgr.savePingTarget(pingTarget);
             } else {
-                logger.error("Unable to parse configured initial ping target '" + configuredTargets[i] + "'. Skipping this target. Check your setting of the property " + PINGS_INITIAL_COMMON_TARGETS_PROP);
+                logger.error("Unable to parse configured initial ping target '" + thisTarget + "'. Skipping this target. Check your setting of the property " + PINGS_INITIAL_COMMON_TARGETS_PROP);
             }
         }
+    }
+
+    /**
+     * Initialize known ping variants from the configuration.
+     */
+    public static void initializePingVariants() {
+        String configuredVal = RollerConfig.getProperty(PINGS_VARIANT_OPTIONS_PROP);
+        if (configuredVal == null || configuredVal.trim().length() == 0) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("No (or empty) value of " + PINGS_VARIANT_OPTIONS_PROP + " present in the configuration.  Skipping initialization of ping variants.");
+            }
+            return;
+        }
+        String[] variants = configuredVal.trim().split(",");
+        for (int i = 0; i < variants.length; i++) {
+            String thisVariant = variants[i].trim();
+            if (thisVariant.length() == 0) continue;
+            Matcher m = NESTED_BRACE_PAIR.matcher(thisVariant);
+            if (m.matches() && m.groupCount() == 2) {
+                String url = m.group(1).trim();
+                String optionsList = m.group(2).trim();
+                Set variantOptions = new HashSet();
+                String[] options = optionsList.split(",");
+                for (int j = 0; j < options.length; j++) {
+                    String option = options[j].trim().toLowerCase();
+                    if (option.length() > 0) {
+                        variantOptions.add(option);
+                    }
+                }
+                if (!variantOptions.isEmpty()) {
+                    configuredVariants.put(url, variantOptions);
+                } else {
+                    logger.warn("Ping variant entry for url '" + url + "' has an empty variant options list.  Ignored.");
+                }
+            } else {
+                logger.error("Unable to parse configured ping variant '" + thisVariant + "'. Skipping this variant. Check your setting of the property " + PINGS_VARIANT_OPTIONS_PROP);
+            }
+        }
+    }
+
+    /**
+     * Get the set of variant options configured for the given ping target url.
+     *
+     * @param pingTargetUrl
+     * @return the set of variant options configured for the given ping target url, or
+     *         the empty set if there are no variants configured.
+     */
+    public static Set getVariantOptions(String pingTargetUrl) {
+        Set variantOptions = (Set) configuredVariants.get(pingTargetUrl);
+        if (variantOptions == null) {
+            variantOptions = Collections.EMPTY_SET;
+        }
+        return variantOptions;
     }
 
 

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/RollerContext.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/RollerContext.java?rev=424677&r1=424676&r2=424677&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/RollerContext.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/RollerContext.java Sat Jul 22 22:45:43 2006
@@ -272,7 +272,9 @@
         
         // Initialize common targets from the configuration
         PingConfig.initializeCommonTargets();
-        // Remove csutom ping targets if they have been disallowed
+        // Initialize ping variants
+        PingConfig.initializePingVariants();
+        // Remove custom ping targets if they have been disallowed
         if (PingConfig.getDisallowCustomTargets()) {
             mLogger.info("Custom ping targets have been disallowed.  Removing any existing custom targets.");
             roller.getPingTargetManager().removeAllCustomPingTargets();

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/pings/WeblogUpdatePinger.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/pings/WeblogUpdatePinger.java?rev=424677&r1=424676&r2=424677&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/pings/WeblogUpdatePinger.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/core/pings/WeblogUpdatePinger.java Sat Jul 22 22:45:43 2006
@@ -21,6 +21,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.roller.RollerException;
+import org.apache.roller.config.PingConfig;
 import org.apache.roller.pojos.PingTargetData;
 import org.apache.roller.pojos.WebsiteData;
 import org.apache.xmlrpc.XmlRpcClient;
@@ -29,12 +30,17 @@
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.UnknownHostException;
-import java.util.Hashtable;
-import java.util.Vector;
+import java.util.*;
 
 /**
  * Utility for sending a weblog update ping.
  *
+ * This implements the <code>WeblogUpdates.ping<code> XML-RPC call described at
+ * <a href="http://www.xmlrpc.com/weblogsCom">www.xmlrpc.com</a>
+ * as well as some variants required to interoperate with certain
+ * buggy but popular ping targets.
+ *
+ *
  * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
  * @author llavandowska (for code refactored from the now-defunct <code>RollerXmlRpcClient</code>)
  */
@@ -50,7 +56,7 @@
 
         public PingResult(Boolean error, String message) {
             this.error = error != null ? error.booleanValue() : false;
-            this.message = message;
+            this.message = message != null ? message : "";
         }
 
         public boolean isError() {
@@ -90,23 +96,42 @@
      * @throws RollerException
      */
     public static PingResult sendPing(String absoluteContextUrl, PingTargetData pingTarget, WebsiteData website) throws RollerException, IOException, XmlRpcException {
-        // Figure out the url of the user's website.
         String websiteUrl = website.getAbsoluteURL();
+        String pingTargetUrl = pingTarget.getPingUrl();
+        Set variantOptions = PingConfig.getVariantOptions(pingTargetUrl);
 
         // Set up the ping parameters.
         Vector params = new Vector();
-        params.addElement(website.getName());
+        if (!variantOptions.contains("noname")) {
+            // ping variant for icerocket and anyone with similar bug, where we must omit the blog name.
+            params.addElement(website.getName());
+        }
         params.addElement(websiteUrl);
         if (logger.isDebugEnabled()) {
-            logger.debug("Executing ping to '" + pingTarget.getPingUrl() + "' for website '" + websiteUrl + "' (" + website.getName() + ")");
+            logger.debug("Executing ping to '" + pingTargetUrl + "' for website '" + websiteUrl + "' (" + website.getName() + ")" + (variantOptions.isEmpty() ? "" : " with variant options " + variantOptions));
         }
 
-        // Send the ping
-        XmlRpcClient client = new XmlRpcClient(pingTarget.getPingUrl());
-        Hashtable result = (Hashtable) client.execute("weblogUpdates.ping", params);
-        PingResult pingResult = new PingResult((Boolean) result.get("flerror"), (String) result.get("message"));
+        // Send the ping.
+        XmlRpcClient client = new XmlRpcClient(pingTargetUrl);
+        PingResult pingResult = parseResult(client.execute("weblogUpdates.ping", params));
+
         if (logger.isDebugEnabled()) logger.debug("Ping result is: " + pingResult);
         return pingResult;
+    }
+
+    private static PingResult parseResult(Object obj) {
+        // Deal with the fact that some buggy ping targets may not respond with the proper struct type.
+        if (obj == null) return new PingResult(null,null);
+        try {
+            // normal case: response is a struct (represented as a Hashtable) with Boolean flerror and String fields.
+            Hashtable result = (Hashtable) obj;
+            return new PingResult((Boolean) result.get("flerror"), (String) result.get("message"));
+        } catch (Exception ex) {
+            // exception case:  The caller responded with an unexpected type, though parsed at the basic XML RPC level.
+            // This effectively assumes flerror = false, and sets message = obj.toString();
+            if (logger.isDebugEnabled()) logger.debug("Invalid ping result of type: " + obj.getClass().getName() + "; proceeding with stand-in representative.");
+            return new PingResult(null,obj.toString());
+        }
     }
 
     /**

Modified: incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties?rev=424677&r1=424676&r2=424677&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties (original)
+++ incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties Sat Jul 22 22:45:43 2006
@@ -290,7 +290,13 @@
 ,{{Weblogs.com}{http://rpc.weblogs.com/RPC2}}\
 ,{{blo.gs}{http://ping.blo.gs/}}\
 ,{{java.blogs}{http://javablogs.com/xmlrpc}}\
-,{{blogrolling.com}{http://rpc.blogrolling.com/pinger/}}
+,{{blogrolling.com}{http://rpc.blogrolling.com/pinger/}}\
+,{{IceRocket}{http://rpc.icerocket.com:10080/}}
+
+# Specify variant options for known buggy ping targets.
+pings.variantOptions=\
+{{http://rpc.icerocket.com:10080/}{noname}}
+
 
 # This controls whether users are allowed to add custom ping targets.  
 # Set this to false to disallow adding custom targets; if false, the