KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > config > PingConfig


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.config;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.roller.RollerException;
24 import org.apache.roller.model.PingTargetManager;
25 import org.apache.roller.model.RollerFactory;
26 import org.apache.roller.pojos.PingTargetData;
27
28 import java.util.*;
29 import java.util.regex.Matcher JavaDoc;
30 import java.util.regex.Pattern JavaDoc;
31
32 // This may need to move to a different package, but it seems appropriate here in the current structure.
33
// Previous placement in the presentation.pings package introduced the undesirable dependency of the
34
// business package on the presentation package.
35

36 /**
37  * Thin wrapper around RollerConfig and RollerRuntimeConfig for centralizing access to the many configurable
38  * settings for pings.
39  *
40  * @author <a HREF="mailto:anil@busybuddha.org">Anil Gangolli</a>
41  */

42 public class PingConfig {
43     private static final Log logger = LogFactory.getLog(PingConfig.class);
44
45
46     // Config property for maximim ping attempts.
47
static final String JavaDoc MAX_PING_ATTEMPTS_PROP = "pings.maxPingAttempts";
48     private static final int MAX_PING_ATTEMPTS_DEFAULT = 3;
49     private static final int MAX_PING_ATTEMPTS_MIN = 1;
50     private static final int MAX_PING_ATTEMPTS_MAX = 10;
51
52     // Config property for queue processing interval
53
private static final String JavaDoc QUEUE_PROCESSING_INTERVAL_PROP = "pings.queueProcessingIntervalMins";
54     private static final int QUEUE_PROCESSING_INTERVAL_DEFAULT = 5;
55     private static final int QUEUE_PROCESSING_INTERVAL_MIN = 0;
56     private static final int QUEUE_PROCESSING_INTERVAL_MAX = 120;
57
58     // PingConfig property for logging pings (not actually performing them). Used for debugging.
59
private static final String JavaDoc PINGS_LOG_ONLY_PROP = "pings.logOnly";
60     private static final boolean PINGS_LOG_ONLY_DEFAULT = false;
61
62     // PingConfig property for controlling whether or not to allow custom ping targets
63
// ("Weblog:Custom Ping Targets" page and actions). If absent, this defaults to false.
64
// with the enabledProperty behavior in editor-menu.xml.
65
// NOTE: If this property name is changed, editor-menu.xml must also be adjusted.
66
private static final String JavaDoc PINGS_DISALLOW_CUSTOM_TARGETS_PROP = "pings.disallowCustomTargets";
67     private static final boolean PINGS_DISALLOW_CUSTOM_TARGETS_DEFAULT = false;
68
69     // PingConfig property for controlling whether or not to allow usage of pings
70
// ("Weblog:Pings" page and actions). If absent, this defaults to false
71
// NOTE: If this property name is changed, editor-menu.xml must also be adjusted.
72
private static final String JavaDoc PINGS_DISABLE_PING_USAGE_PROP = "pings.disablePingUsage";
73     private static final boolean PINGS_DISABLE_PING_USAGE_DEFAULT = false;
74
75     // PingConfig property for controlling suspending the processing of pings. If true,
76
// new auto ping requests are not queued, any existing queued requests are not processed,
77
// and sending a manual ping results in a message saying pings have been disabled.
78
// NOTE: This is a "runtime" property settable on the Admin:PingConfig page, default is false.
79
private static final String JavaDoc PINGS_SUSPEND_PING_PROCESSING_PROP = "pings.suspendPingProcessing";
80
81     // PingConfig property determining the initial common ping targets. If the list of common
82
// ping targets is empty on startup, the value of this property is used to populate initial values.
83
// The value takes the form of comma-separated ping targets where each ping target is specified in
84
// the form {{name}{pingurl}}. If an administrator wants to disable this initialization, in order to
85
// maintain an empty list of common targets, the administrator can disable the initialization by
86
// commenting out this property in the config file.
87
private static final String JavaDoc PINGS_INITIAL_COMMON_TARGETS_PROP = "pings.initialCommonTargets";
88
89
90     // PingConfig property determining the known WeblogUpdates.ping variants/bugs
91
// in popular ping targets, which we are used when invoking pings on those targets.
92
// The value takes the form of a comma separated list of ping target urls and
93
// variant options, where each one is in the form {{pingurl}{option[[,option]...]}}.
94
private static final String JavaDoc PINGS_VARIANT_OPTIONS_PROP = "pings.variantOptions";
95     // Map of configured ping variants. Maps a ping target hostname to a set of
96
// Strings representing variant options to be used when pinging this target.
97
// This was introduced in order to support certain buggy (but popular) ping
98
// targets that implement minor variants of the WeblogUpdates.ping call.
99
// This is initialized once at startup, and referenced when pings are made.
100
private static final Map configuredVariants = new HashMap();
101
102
103     // Inhibit construction
104
private PingConfig() {
105     }
106
107     /**
108      * Get the maximum number of ping attempts that should be made for each ping queue entry before we give up. If we
109      * get apparently transient failures while trying to perform the ping, the entry is requeued for processing on later
110      * passes through the queue until this number of attempts has been reached.
111      *
112      * @return the configured (or default) maximum number of ping attempts
113      */

114     public static int getMaxPingAttempts() {
115         return getIntegerProperty(MAX_PING_ATTEMPTS_PROP, MAX_PING_ATTEMPTS_DEFAULT, MAX_PING_ATTEMPTS_MIN, MAX_PING_ATTEMPTS_MAX);
116     }
117
118     /**
119      * Get the ping queue processing interval in minutes.
120      *
121      * @return the configured (or default) queue processing interval in minutes.
122      */

123     public static int getQueueProcessingIntervalMins() {
124         return getIntegerProperty(QUEUE_PROCESSING_INTERVAL_PROP, QUEUE_PROCESSING_INTERVAL_DEFAULT, QUEUE_PROCESSING_INTERVAL_MIN, QUEUE_PROCESSING_INTERVAL_MAX);
125     }
126
127
128     /**
129      * Get the logs only setting. Get configuration value determining whether pings are to be logged only (not sent).
130      * This configuration setting is used for development and debugging.
131      *
132      * @return the configured (or default) value of the logs only setting.
133      */

134     public static boolean getLogPingsOnly() {
135         return getBooleanProperty(PINGS_LOG_ONLY_PROP, PINGS_LOG_ONLY_DEFAULT);
136     }
137
138     /**
139      * Determine whether the configuration disallows custom ping targets. If this is true, users are not allowed to
140      * create or edit custom ping targets, and any auto ping configs that use them are ignored.
141      *
142      * @return the configured (or default) value of the "disallow custom targets" setting.
143      */

144     public static boolean getDisallowCustomTargets() {
145         return getBooleanProperty(PINGS_DISALLOW_CUSTOM_TARGETS_PROP, PINGS_DISALLOW_CUSTOM_TARGETS_DEFAULT);
146     }
147
148     /**
149      * Determine whether the configuration disables ping usage (configuration of auto pings and sending of manual
150      * pings). If this is true, all auto ping configus are removed at startup, the Weblog:Pings UI and the associated
151      * actions are disabled.
152      *
153      * @return the configured (or default) value of the enable ping usage setting.
154      */

155     public static boolean getDisablePingUsage() {
156         return getBooleanProperty(PINGS_DISABLE_PING_USAGE_PROP, PINGS_DISABLE_PING_USAGE_DEFAULT);
157     }
158
159     /**
160      * Determine whether ping processing is suspended. If this is true, new auto ping requests are not
161      * queued, any existing queued requests are not processed, and sending a manual ping results in a message saying
162      * pings have been disabled.
163      *
164      * @return the configured (or default) value of the suspend ping processing setting.
165      */

166     public static boolean getSuspendPingProcessing() {
167         return RollerRuntimeConfig.getBooleanProperty(PINGS_SUSPEND_PING_PROCESSING_PROP);
168     }
169
170     // Pattern used to parse common ping targets as well as ping variants.
171
// Each initial commmon ping target is specified in the format {{name}{url}}
172
// Ping variants are also specified in a nested brace format {{url}{options}}
173
private static final Pattern JavaDoc NESTED_BRACE_PAIR = Pattern.compile("\\{\\{(.*?)\\}\\{(.*?)\\}\\}");
174
175     /**
176      * Initialize the common ping targets from the configuration properties. If the current list of common ping targets
177      * is empty, and the <code>PINGS_INITIAL_COMMON_TARGETS_PROP</code> property is present in the configuration then,
178      * this method will use that value to initialize the common targets. This is called on each server startup.
179      * <p/>
180      * Note: this is expected to be called during initialization with transaction demarcation being handled by the
181      * caller.
182      *
183      * @see org.apache.roller.ui.core.RollerContext#contextInitialized(javax.servlet.ServletContextEvent)
184      */

185     public static void initializeCommonTargets() throws RollerException {
186         String JavaDoc configuredVal = RollerConfig.getProperty(PINGS_INITIAL_COMMON_TARGETS_PROP);
187         if (configuredVal == null || configuredVal.trim().length() == 0) {
188             if (logger.isDebugEnabled()) {
189                 logger.debug("No (or empty) value of " + PINGS_INITIAL_COMMON_TARGETS_PROP + " present in the configuration. Skipping initialization of commmon targets.");
190             }
191             return;
192         }
193         PingTargetManager pingTargetMgr = RollerFactory.getRoller().getPingTargetManager();
194         if (!pingTargetMgr.getCommonPingTargets().isEmpty()) {
195             if (logger.isDebugEnabled()) {
196                 logger.debug("Some common ping targets are present in the database already. Skipping initialization.");
197             }
198             return;
199         }
200
201         String JavaDoc[] configuredTargets = configuredVal.trim().split(",");
202         for (int i = 0; i < configuredTargets.length; i++) {
203             // Trim space around the target spec
204
String JavaDoc thisTarget = configuredTargets[i].trim();
205             // skip empty ones
206
if (thisTarget.length() == 0) continue;
207             // parse the ith target and store it
208
Matcher JavaDoc m = NESTED_BRACE_PAIR.matcher(thisTarget);
209             if (m.matches() && m.groupCount() == 2) {
210                 String JavaDoc name = m.group(1).trim();
211                 String JavaDoc url = m.group(2).trim();
212                 logger.info("Creating common ping target '" + name + "' from configuration properties.");
213                 PingTargetData pingTarget = new PingTargetData(null, name, url, null, false);
214                 pingTargetMgr.savePingTarget(pingTarget);
215             } else {
216                 logger.error("Unable to parse configured initial ping target '" + thisTarget + "'. Skipping this target. Check your setting of the property " + PINGS_INITIAL_COMMON_TARGETS_PROP);
217             }
218         }
219     }
220
221     /**
222      * Initialize known ping variants from the configuration.
223      */

224     public static void initializePingVariants() {
225         String JavaDoc configuredVal = RollerConfig.getProperty(PINGS_VARIANT_OPTIONS_PROP);
226         if (configuredVal == null || configuredVal.trim().length() == 0) {
227             if (logger.isDebugEnabled()) {
228                 logger.debug("No (or empty) value of " + PINGS_VARIANT_OPTIONS_PROP + " present in the configuration. Skipping initialization of ping variants.");
229             }
230             return;
231         }
232         String JavaDoc[] variants = configuredVal.trim().split(",");
233         for (int i = 0; i < variants.length; i++) {
234             String JavaDoc thisVariant = variants[i].trim();
235             if (thisVariant.length() == 0) continue;
236             Matcher JavaDoc m = NESTED_BRACE_PAIR.matcher(thisVariant);
237             if (m.matches() && m.groupCount() == 2) {
238                 String JavaDoc url = m.group(1).trim();
239                 String JavaDoc optionsList = m.group(2).trim();
240                 Set variantOptions = new HashSet();
241                 String JavaDoc[] options = optionsList.split(",");
242                 for (int j = 0; j < options.length; j++) {
243                     String JavaDoc option = options[j].trim().toLowerCase();
244                     if (option.length() > 0) {
245                         variantOptions.add(option);
246                     }
247                 }
248                 if (!variantOptions.isEmpty()) {
249                     configuredVariants.put(url, variantOptions);
250                 } else {
251                     logger.warn("Ping variant entry for url '" + url + "' has an empty variant options list. Ignored.");
252                 }
253             } else {
254                 logger.error("Unable to parse configured ping variant '" + thisVariant + "'. Skipping this variant. Check your setting of the property " + PINGS_VARIANT_OPTIONS_PROP);
255             }
256         }
257     }
258
259     /**
260      * Get the set of variant options configured for the given ping target url.
261      *
262      * @param pingTargetUrl
263      * @return the set of variant options configured for the given ping target url, or
264      * the empty set if there are no variants configured.
265      */

266     public static Set getVariantOptions(String JavaDoc pingTargetUrl) {
267         Set variantOptions = (Set) configuredVariants.get(pingTargetUrl);
268         if (variantOptions == null) {
269             variantOptions = Collections.EMPTY_SET;
270         }
271         return variantOptions;
272     }
273
274
275     // TODO: Refactor functionality below to RollerConfig?
276

277     /**
278      * Get the value of an integer configuration property.
279      *
280      * @param propName the property name
281      * @param defaultValue the default value if the property is not present
282      * @param min the minimum allowed value
283      * @param max the maximum allowed value
284      * @return the value as an integer; the default value if no configured value is present or if the configured value
285      * is out of the specified range.
286      */

287     private static int getIntegerProperty(String JavaDoc propName, int defaultValue, int min, int max) {
288         String JavaDoc configuredVal = RollerConfig.getProperty(propName);
289         if (configuredVal == null) {
290             if (logger.isDebugEnabled()) {
291                 logger.debug("PingConfig property '" + propName + "' is not present in the configuration. Using default value: " + defaultValue);
292             }
293             return defaultValue;
294         }
295
296         int val;
297         try {
298             val = Integer.parseInt(configuredVal);
299         } catch (NumberFormatException JavaDoc ex) {
300             logger.error("ERROR: PingConfig property '" + propName + "' is not an integer value. Using default value: " + defaultValue);
301             return defaultValue;
302         }
303
304         if (val < min || val > max) {
305             logger.error("ERROR: PingConfig property '" + propName + "' is outside the required range (" + min + ", " + max + "). Using default value: " + defaultValue);
306             return defaultValue;
307         }
308
309         return val;
310     }
311
312     /**
313      * Get the value of a boolean property with specified default.
314      *
315      * @param propName the property name
316      * @param defaultValue the default value if the property is not present
317      * @return the configured value or the default if it the configured value is not present.
318      */

319     private static boolean getBooleanProperty(String JavaDoc propName, boolean defaultValue) {
320         String JavaDoc configuredVal = RollerConfig.getProperty(propName);
321         if (configuredVal == null) {
322             if (logger.isDebugEnabled()) {
323                 logger.debug("PingConfig property '" + propName + "' is not present in the configuration. Using default value: " + defaultValue);
324             }
325             return defaultValue;
326         }
327         return Boolean.valueOf(configuredVal).booleanValue();
328     }
329
330
331 }
332
Popular Tags