File Source: WeblogUpdatePinger.java
/*
P/P * Method: org.apache.roller.weblogger.business.pings.WeblogUpdatePinger$PingResult__static_init
*/
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19 package org.apache.roller.weblogger.business.pings;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.roller.weblogger.config.PingConfig;
24 import org.apache.roller.weblogger.pojos.PingTarget;
25 import org.apache.roller.weblogger.pojos.Weblog;
26 import org.apache.xmlrpc.XmlRpcException;
27 import org.apache.xmlrpc.client.XmlRpcClient;
28 import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
29
30 import java.io.IOException;
31 import java.net.MalformedURLException;
32 import java.net.URL;
33 import java.net.UnknownHostException;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38
39 /**
40 * Utility for sending a weblog update ping.
41 *
42 * This implements the <code>WeblogUpdates.ping<code> XML-RPC call described at
43 * <a href="http://www.xmlrpc.com/weblogsCom">www.xmlrpc.com</a>
44 * as well as some variants required to interoperate with certain
45 * buggy but popular ping targets.
46 *
47 *
48 * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
49 * @author llavandowska (for code refactored from the now-defunct <code>RollerXmlRpcClient</code>)
50 */
51 public class WeblogUpdatePinger {
/*
P/P * Method: org.apache.roller.weblogger.business.pings.WeblogUpdatePinger__static_init
*
* Postconditions:
* init'ed(logger)
*/
52 public static final Log logger = LogFactory.getLog(WeblogUpdatePinger.class);
53
54 /**
55 * Conveys a ping result.
56 */
57 public static class PingResult {
58 boolean error;
59 String message;
60
/*
P/P * Method: void org.apache.roller.weblogger.business.pings.WeblogUpdatePinger$PingResult(Boolean, String)
*
* Postconditions:
* init'ed(this.error)
* this.message == One-of{message, &""}
* this.message != null
*/
61 public PingResult(Boolean error, String message) {
62 this.error = error != null ? error.booleanValue() : false;
63 this.message = message != null ? message : "";
64 }
65
66 public boolean isError() {
/*
P/P * Method: bool isError()
*
* Preconditions:
* init'ed(this.error)
*
* Postconditions:
* return_value == this.error
* init'ed(return_value)
*/
67 return error;
68 }
69
70 public void setError(boolean error) {
/*
P/P * Method: void setError(bool)
*
* Postconditions:
* this.error == error
* init'ed(this.error)
*/
71 this.error = error;
72 }
73
74 public String getMessage() {
/*
P/P * Method: String getMessage()
*
* Preconditions:
* init'ed(this.message)
*
* Postconditions:
* return_value == this.message
* init'ed(return_value)
*/
75 return message;
76 }
77
78 public void setMessage(String message) {
/*
P/P * Method: void setMessage(String)
*
* Postconditions:
* this.message == message
* init'ed(this.message)
*/
79 this.message = message;
80 }
81
82 public String toString() {
/*
P/P * Method: String toString()
*
* Preconditions:
* init'ed(this.error)
* init'ed(this.message)
*
* Postconditions:
* init'ed(java.lang.StringBuilder:toString(...)._tainted)
* return_value == &java.lang.StringBuilder:toString(...)
*/
83 return "PingResult{" + "error=" + error + ", message='" + message + "'" + "}";
84 }
85 }
86
87 // Inhibit construction
/*
P/P * Method: void org.apache.roller.weblogger.business.pings.WeblogUpdatePinger()
*/
88 private WeblogUpdatePinger() {
89 }
90
91 /**
92 * Send a weblog update ping.
93 *
94 * @param pingTarget the target site to ping
95 * @param website the website that changed (from which the ping originates)
96 * @return the result message string sent by the server.
97 * @throws IOException if an IOException occurs during the ping
98 * @throws XmlRpcException if the XML RPC client throws one
99 */
100 public static PingResult sendPing(PingTarget pingTarget, Weblog website) throws IOException, XmlRpcException {
/*
P/P * Method: WeblogUpdatePinger$PingResult sendPing(PingTarget, Weblog)
*
* Preconditions:
* pingTarget != null
* website != null
*
* Presumptions:
* org.apache.commons.logging.LogFactory:getLog(...)@52 != null
*
* Postconditions:
* init'ed(java.lang.Object:toString(...)._tainted)
* return_value == One-of{&new WeblogUpdatePinger$PingResult(parseResult#1), &new WeblogUpdatePinger$PingResult(parseResult#2), &new WeblogUpdatePinger$PingResult(parseResult#4)}
* return_value in Addr_Set{&new WeblogUpdatePinger$PingResult(parseResult#1),&new WeblogUpdatePinger$PingResult(parseResult#2),&new WeblogUpdatePinger$PingResult(parseResult#4)}
* new WeblogUpdatePinger$PingResult(parseResult#1) num objects <= 1
* new WeblogUpdatePinger$PingResult(parseResult#1)._tainted == 0
* new WeblogUpdatePinger$PingResult(parseResult#2)._tainted == 0
* new WeblogUpdatePinger$PingResult(parseResult#4)._tainted == 0
* init'ed(new WeblogUpdatePinger$PingResult(parseResult#1).error)
* new WeblogUpdatePinger$PingResult(parseResult#1).message == &""
* new WeblogUpdatePinger$PingResult(parseResult#2) num objects <= 1
* ...
*
* Test Vectors:
* java.util.Set:contains(...)@107: {1}, {0}
* org.apache.commons.logging.Log:isDebugEnabled(...)@112: {0}, {1}
* org.apache.commons.logging.Log:isDebugEnabled(...)@123: {0}, {1}
*/
101 String websiteUrl = website.getAbsoluteURL();
102 String pingTargetUrl = pingTarget.getPingUrl();
103 Set variantOptions = PingConfig.getVariantOptions(pingTargetUrl);
104
105 // Set up the ping parameters.
106 List params = new ArrayList();
+ 107 if (!variantOptions.contains("noname")) {
108 // ping variant for icerocket and anyone with similar bug, where we must omit the blog name.
109 params.add(website.getName());
110 }
111 params.add(websiteUrl);
112 if (logger.isDebugEnabled()) {
113 logger.debug("Executing ping to '" + pingTargetUrl + "' for website '" + websiteUrl + "' (" + website.getName() + ")" + (variantOptions.isEmpty() ? "" : " with variant options " + variantOptions));
114 }
115
116 // Send the ping.
117 XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
118 config.setServerURL(new URL(pingTargetUrl));
119 XmlRpcClient client = new XmlRpcClient();
120 client.setConfig(config);
121 PingResult pingResult = parseResult(client.execute("weblogUpdates.ping", params.toArray()));
122
123 if (logger.isDebugEnabled()) logger.debug("Ping result is: " + pingResult);
124 return pingResult;
125 }
126
127 private static PingResult parseResult(Object obj) {
128 // Deal with the fact that some buggy ping targets may not respond with the proper struct type.
/*
P/P * Method: WeblogUpdatePinger$PingResult parseResult(Object)
*
* Presumptions:
* java.lang.Object:getClass(...)@137 != null
* org.apache.commons.logging.LogFactory:getLog(...)@52 != null
*
* Postconditions:
* init'ed(java.lang.Object:toString(...)._tainted)
* return_value in Addr_Set{&new WeblogUpdatePinger$PingResult(parseResult#2),&new WeblogUpdatePinger$PingResult(parseResult#4),&new WeblogUpdatePinger$PingResult(parseResult#1)}
* new WeblogUpdatePinger$PingResult(parseResult#1) num objects <= 1
* init'ed(new WeblogUpdatePinger$PingResult(parseResult#1).error)
* new WeblogUpdatePinger$PingResult(parseResult#1).message == &""
* new WeblogUpdatePinger$PingResult(parseResult#2) num objects <= 1
* init'ed(new WeblogUpdatePinger$PingResult(parseResult#2).error)
* new WeblogUpdatePinger$PingResult(parseResult#2).message != null
* new WeblogUpdatePinger$PingResult(parseResult#4) num objects <= 1
* init'ed(new WeblogUpdatePinger$PingResult(parseResult#4).error)
* ...
*
* Test Vectors:
* obj: Inverse{null}, Addr_Set{null}
*/
129 if (obj == null) return new PingResult(null,null);
130 try {
131 // normal case: response is a struct (represented as a Map) with Boolean flerror and String fields.
132 Map result = (Map) obj;
133 return new PingResult((Boolean) result.get("flerror"), (String) result.get("message"));
134 } catch (Exception ex) {
135 // exception case: The caller responded with an unexpected type, though parsed at the basic XML RPC level.
136 // This effectively assumes flerror = false, and sets message = obj.toString();
137 if (logger.isDebugEnabled()) logger.debug("Invalid ping result of type: " + obj.getClass().getName() + "; proceeding with stand-in representative.");
138 return new PingResult(null,obj.toString());
139 }
140 }
141
142 /**
143 * Decide if the given exception appears to warrant later retrial attempts.
144 *
145 * @param ex an exception thrown by the <coce>sendPing</code> operation
146 * @return true if the error warrants retrial
147 */
148 public static boolean shouldRetry(Exception ex) {
149 // Determine if error appears transient (warranting retrial)
150 // We give most errors the "benefit of the doubt" by considering them transient
151 // This picks out a few that we consider non-transient
/*
P/P * Method: bool shouldRetry(Exception)
*
* Postconditions:
* init'ed(return_value)
*/
152 if (ex instanceof UnknownHostException) {
153 // User probably mistyped the url in the custom target.
154 return false;
155 } else if (ex instanceof MalformedURLException) {
156 // This should never happen due to validations but if we get here, retrial won't fix it.
157 return false;
158 }
159 return true;
160 }
161
162 }
SofCheck Inspector Build Version : 2.18479
| WeblogUpdatePinger.java |
2009-Jan-02 14:24:48 |
| WeblogUpdatePinger.class |
2009-Sep-04 03:12:31 |
| WeblogUpdatePinger$PingResult.class |
2009-Sep-04 03:12:31 |