001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.ui.authoring.struts.actions;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023: import org.apache.roller.RollerException;
024: import org.apache.roller.config.PingConfig;
025: import org.apache.roller.business.pings.AutoPingManager;
026: import org.apache.roller.business.pings.PingTargetManager;
027: import org.apache.roller.business.RollerFactory;
028: import org.apache.roller.pojos.AutoPingData;
029: import org.apache.roller.pojos.PingTargetData;
030: import org.apache.roller.pojos.WebsiteData;
031: import org.apache.roller.ui.core.BasePageModel;
032: import org.apache.roller.ui.core.RequestConstants;
033: import org.apache.roller.ui.core.RollerRequest;
034: import org.apache.roller.ui.core.RollerSession;
035: import org.apache.roller.business.pings.WeblogUpdatePinger;
036: import org.apache.struts.action.*;
037: import org.apache.struts.actions.DispatchAction;
038: import org.apache.xmlrpc.XmlRpcException;
039:
040: import javax.servlet.ServletException;
041: import javax.servlet.http.HttpServletRequest;
042: import javax.servlet.http.HttpServletResponse;
043: import java.io.IOException;
044: import java.net.SocketException;
045: import java.net.UnknownHostException;
046: import java.util.*;
047:
048: /**
049: * Actions for setting up automatic ping configuration for a weblog.
050: *
051: * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
052: * @struts.action name="pingSetupForm" path="/roller-ui/authoring/pingSetup" scope="request" parameter="method"
053: * @struts.action-forward name="pingSetup.page" path=".Pings"
054: * @struts.action-forward name="pingResult.page" path=".PingResult"
055: */
056: public class PingSetupAction extends DispatchAction {
057: private static Log mLogger = LogFactory.getFactory().getInstance(
058: PingSetupAction.class);
059:
060: private static final String PING_SETUP_PAGE = "pingSetup.page";
061:
062: /* (non-Javadoc)
063: * @see org.apache.struts.actions.DispatchAction#unspecified(
064: * org.apache.struts.action.ActionMapping,
065: * org.apache.struts.action.ActionForm,
066: * javax.servlet.http.HttpServletRequest,
067: * javax.servlet.http.HttpServletResponse)
068: */
069: protected ActionForward unspecified(ActionMapping mapping,
070: ActionForm actionForm, HttpServletRequest request,
071: HttpServletResponse response) throws Exception {
072: return view(mapping, actionForm, request, response);
073: }
074:
075: /*
076: * Display the common ping targets with page
077: */
078: public ActionForward view(ActionMapping mapping, ActionForm form,
079: HttpServletRequest req, HttpServletResponse res)
080: throws Exception {
081: ActionForward forward = mapping.findForward(PING_SETUP_PAGE);
082: RollerRequest rreq = RollerRequest.getRollerRequest(req);
083: PingTargetManager pingTargetMgr = RollerFactory.getRoller()
084: .getPingTargetManager();
085: WebsiteData website = rreq.getWebsite();
086: try {
087: if (!isAuthorized(rreq, website)) {
088: return mapping.findForward("access-denied");
089: }
090:
091: BasePageModel pageModel = new BasePageModel("pings.title",
092: req, res, mapping);
093: req.setAttribute("model", pageModel);
094:
095: List commonPingTargets = pingTargetMgr
096: .getCommonPingTargets();
097: req.setAttribute("commonPingTargets", commonPingTargets);
098:
099: Boolean allowCustomTargets = new Boolean(!PingConfig
100: .getDisallowCustomTargets());
101: req.setAttribute("allowCustomTargets", allowCustomTargets);
102:
103: List customPingTargets = allowCustomTargets.booleanValue() ? pingTargetMgr
104: .getCustomPingTargets(website)
105: : Collections.EMPTY_LIST;
106: req.setAttribute("customPingTargets", customPingTargets);
107:
108: // Build isEnabled map (keyed by ping target id and values Boolean.TRUE/Boolean.FALSE)
109: Map isEnabled = buildIsEnabledMap(rreq, commonPingTargets,
110: customPingTargets);
111: req.setAttribute("isEnabled", isEnabled);
112:
113: return forward;
114: } catch (Exception e) {
115: mLogger.error("ERROR in action", e);
116: throw new ServletException(e);
117: }
118: }
119:
120: /*
121: * Private helper to build a map indexed by ping target id with values Boolean.TRUE and Boolean.FALSE
122: * based on whether the ping target is enabled (has a corresponding auto ping configuration).
123: */
124: private Map buildIsEnabledMap(RollerRequest rreq,
125: List commonPingTargets, List customPingTargets)
126: throws RollerException {
127: AutoPingManager autoPingMgr = RollerFactory.getRoller()
128: .getAutopingManager();
129: WebsiteData website = rreq.getWebsite();
130:
131: // Build isEnabled map (keyed by ping target id and values Boolean.TRUE/Boolean.FALSE)
132: Map isEnabled = new HashMap();
133: List autopings = autoPingMgr.getAutoPingsByWebsite(website);
134: // Add the enabled auto ping configs with TRUE
135: for (Iterator i = autopings.iterator(); i.hasNext();) {
136: AutoPingData autoPing = (AutoPingData) i.next();
137: isEnabled.put(autoPing.getPingTarget().getId(),
138: Boolean.TRUE);
139: }
140: // Somewhat awkward, but the two loops save building a separate combined list.
141: // Add disabled common ones with FALSE
142: for (Iterator i = commonPingTargets.iterator(); i.hasNext();) {
143: PingTargetData pingTarget = (PingTargetData) i.next();
144: if (isEnabled.get(pingTarget.getId()) == null) {
145: isEnabled.put(pingTarget.getId(), Boolean.FALSE);
146: }
147: }
148: // Add disabled custom ones with FALSE
149: for (Iterator i = customPingTargets.iterator(); i.hasNext();) {
150: PingTargetData pingTarget = (PingTargetData) i.next();
151: if (isEnabled.get(pingTarget.getId()) == null) {
152: isEnabled.put(pingTarget.getId(), Boolean.FALSE);
153: }
154: }
155: return isEnabled;
156: }
157:
158: /*
159: * Enable a ping target.
160: */
161: public ActionForward enableSelected(ActionMapping mapping,
162: ActionForm form, HttpServletRequest req,
163: HttpServletResponse res) throws Exception {
164: RollerRequest rreq = RollerRequest.getRollerRequest(req);
165: AutoPingManager autoPingMgr = RollerFactory.getRoller()
166: .getAutopingManager();
167: PingTargetData pingTarget = select(rreq);
168: try {
169: if (!isAuthorized(rreq, rreq.getWebsite())) {
170: return mapping.findForward("access-denied");
171: }
172: AutoPingData autoPing = new AutoPingData(null, pingTarget,
173: rreq.getWebsite());
174: autoPingMgr.saveAutoPing(autoPing);
175: RollerFactory.getRoller().flush();
176:
177: return view(mapping, form, req, res);
178: } catch (Exception e) {
179: mLogger.error("ERROR in action", e);
180: throw new ServletException(e);
181: }
182: }
183:
184: /*
185: * Load delete confirmation view.
186: */
187: public ActionForward disableSelected(ActionMapping mapping,
188: ActionForm form, HttpServletRequest req,
189: HttpServletResponse res) throws Exception {
190: RollerRequest rreq = RollerRequest.getRollerRequest(req);
191: AutoPingManager autoPingMgr = RollerFactory.getRoller()
192: .getAutopingManager();
193: PingTargetData pingTarget = select(rreq);
194: try {
195: if (!isAuthorized(rreq, rreq.getWebsite())) {
196: return mapping.findForward("access-denied");
197: }
198: autoPingMgr.removeAutoPing(pingTarget, rreq.getWebsite());
199: RollerFactory.getRoller().flush();
200:
201: return view(mapping, form, req, res);
202: } catch (Exception e) {
203: mLogger.error("ERROR in action", e);
204: throw new ServletException(e);
205: }
206: }
207:
208: /*
209: * Ping the selected target now.
210: */
211: public ActionForward pingSelectedNow(ActionMapping mapping,
212: ActionForm form, HttpServletRequest req,
213: HttpServletResponse res) throws Exception {
214: try {
215: RollerRequest rreq = RollerRequest.getRollerRequest(req);
216: PingTargetData pingTarget = select(rreq);
217: WebsiteData website = rreq.getWebsite();
218: try {
219: if (!isAuthorized(rreq, website)) {
220: return mapping.findForward("access-denied");
221: }
222: if (PingConfig.getSuspendPingProcessing()) {
223: if (mLogger.isDebugEnabled())
224: mLogger.debug("Ping processing is disabled.");
225: ActionMessages errors = new ActionMessages();
226: errors.add(ActionMessages.GLOBAL_MESSAGE,
227: new ActionMessage(
228: "ping.pingProcessingIsSuspended"));
229: saveErrors(req, errors);
230: } else {
231: WeblogUpdatePinger.PingResult pingResult = WeblogUpdatePinger
232: .sendPing(pingTarget, website);
233: if (pingResult.isError()) {
234: if (mLogger.isDebugEnabled())
235: mLogger.debug("Ping Result: " + pingResult);
236: ActionMessages errors = new ActionMessages();
237: if (pingResult.getMessage() != null
238: && pingResult.getMessage().trim()
239: .length() > 0) {
240: errors
241: .add(
242: ActionMessages.GLOBAL_MESSAGE,
243: new ActionMessage(
244: "ping.transmittedButError"));
245: errors.add(ActionMessages.GLOBAL_MESSAGE,
246: new ActionMessage(pingResult
247: .getMessage()));
248: } else {
249: errors.add(ActionMessages.GLOBAL_MESSAGE,
250: new ActionMessage(
251: "ping.transmissionFailed"));
252: }
253: saveErrors(req, errors);
254: } else {
255: ActionMessages messages = new ActionMessages();
256: messages.add(ActionMessages.GLOBAL_MESSAGE,
257: new ActionMessage("ping.successful"));
258: saveMessages(req, messages);
259: }
260: }
261: } catch (IOException ex) {
262: mLogger.debug(ex);
263: ActionMessages errors = new ActionMessages();
264: errors.add(ActionMessages.GLOBAL_MESSAGE,
265: new ActionMessage("ping.transmissionFailed"));
266: addSpecificMessages(ex, errors);
267: saveErrors(req, errors);
268: } catch (XmlRpcException ex) {
269: mLogger.debug(ex);
270: ActionMessages errors = new ActionMessages();
271: errors.add(ActionMessages.GLOBAL_MESSAGE,
272: new ActionMessage("ping.transmissionFailed"));
273: addSpecificMessages(ex, errors);
274: saveErrors(req, errors);
275: }
276: return view(mapping, form, req, res);
277: } catch (Exception ex) {
278: mLogger.error("ERROR in action", ex);
279: throw new ServletException(ex);
280: }
281: }
282:
283: // TODO: Consider unifying with other RollerRequest methods
284: // Private helper to get ping target specified by request
285: private PingTargetData select(RollerRequest rreq)
286: throws RollerException {
287: String pingTargetId = rreq.getRequest().getParameter(
288: RequestConstants.PINGTARGET_ID);
289: PingTargetManager pingTargetMgr = RollerFactory.getRoller()
290: .getPingTargetManager();
291: if (pingTargetId == null || pingTargetId.length() == 0) {
292: throw new RollerException("Missing ping target id: "
293: + pingTargetId);
294: }
295:
296: PingTargetData pingTarget = pingTargetMgr
297: .getPingTarget(pingTargetId);
298: if (pingTarget == null) {
299: throw new RollerException("No such ping target id: "
300: + pingTargetId);
301: }
302: return pingTarget;
303: }
304:
305: private void addSpecificMessages(Exception ex, ActionMessages errors) {
306: if (ex instanceof UnknownHostException) {
307: errors.add(ActionMessages.GLOBAL_MESSAGE,
308: new ActionMessage("ping.unknownHost"));
309: } else if (ex instanceof SocketException) {
310: errors.add(ActionMessages.GLOBAL_MESSAGE,
311: new ActionMessage("ping.networkConnectionFailed"));
312: }
313: }
314:
315: private boolean isAuthorized(RollerRequest rreq, WebsiteData website)
316: throws RollerException {
317: RollerSession rses = RollerSession.getRollerSession(rreq
318: .getRequest());
319: return rses.isUserAuthorizedToAdmin(website)
320: && !PingConfig.getDisablePingUsage();
321: }
322: }
|