|
| 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.ui.rendering.servlets; |
| 20 | + |
| 21 | +import java.io.IOException; |
| 22 | +import java.io.PrintWriter; |
| 23 | +import java.sql.Timestamp; |
| 24 | +import java.util.Date; |
| 25 | +import javax.servlet.ServletConfig; |
| 26 | +import javax.servlet.ServletException; |
| 27 | +import javax.servlet.http.HttpServlet; |
| 28 | +import javax.servlet.http.HttpServletRequest; |
| 29 | +import javax.servlet.http.HttpServletResponse; |
| 30 | +import org.apache.commons.logging.Log; |
| 31 | +import org.apache.commons.logging.LogFactory; |
| 32 | +import org.apache.roller.util.RollerConstants; |
| 33 | +import org.apache.roller.weblogger.WebloggerException; |
| 34 | +import org.apache.roller.weblogger.config.WebloggerRuntimeConfig; |
| 35 | +import org.apache.roller.weblogger.business.WebloggerFactory; |
| 36 | +import org.apache.roller.weblogger.business.WeblogEntryManager; |
| 37 | +import org.apache.roller.weblogger.pojos.WeblogEntryComment; |
| 38 | +import org.apache.roller.weblogger.pojos.WeblogEntryComment.ApprovalStatus; |
| 39 | +import org.apache.roller.weblogger.pojos.WeblogEntry; |
| 40 | +import org.apache.roller.weblogger.pojos.Weblog; |
| 41 | +import org.apache.roller.weblogger.ui.rendering.plugins.comments.CommentValidationManager; |
| 42 | +import org.apache.roller.weblogger.ui.rendering.plugins.comments.TrackbackLinkbackCommentValidator; |
| 43 | +import org.apache.roller.weblogger.ui.rendering.util.WeblogTrackbackRequest; |
| 44 | +import org.apache.roller.weblogger.util.I18nMessages; |
| 45 | +import org.apache.roller.weblogger.util.MailUtil; |
| 46 | +import org.apache.roller.weblogger.util.RollerMessages; |
| 47 | +import org.apache.roller.weblogger.util.cache.CacheManager; |
| 48 | + |
| 49 | + |
| 50 | +/** |
| 51 | + * Roller's Trackback server implementation. POSTing to this Servlet will add a |
| 52 | + * Trackback to a Weblog Entry. For more info on Trackback, read the spec: |
| 53 | + * <a href="http://www.movabletype.org/documentation/trackback/specification.html">MT Trackback</a>. |
| 54 | + */ |
| 55 | +public class TrackbackServlet extends HttpServlet { |
| 56 | + |
| 57 | + private static Log logger = LogFactory.getLog(TrackbackServlet.class); |
| 58 | + |
| 59 | + private CommentValidationManager commentValidationManager = null; |
| 60 | + |
| 61 | + |
| 62 | + @Override |
| 63 | + public void init(ServletConfig config) throws ServletException { |
| 64 | + commentValidationManager = new CommentValidationManager(); |
| 65 | + |
| 66 | + // add trackback verification validator just for trackbacks |
| 67 | + commentValidationManager.addCommentValidator(new TrackbackLinkbackCommentValidator()); |
| 68 | + } |
| 69 | + |
| 70 | + |
| 71 | + /** |
| 72 | + * Handle incoming http GET requests. |
| 73 | + * |
| 74 | + * The TrackbackServlet does not support GET requests, it's a 404. |
| 75 | + */ |
| 76 | + @Override |
| 77 | + public void doGet(HttpServletRequest request, HttpServletResponse response) |
| 78 | + throws IOException, ServletException { |
| 79 | + |
| 80 | + response.sendError(HttpServletResponse.SC_NOT_FOUND); |
| 81 | + } |
| 82 | + |
| 83 | + |
| 84 | + /** |
| 85 | + * Service incoming POST requests. |
| 86 | + * |
| 87 | + * Here we handle incoming trackback posts. |
| 88 | + */ |
| 89 | + @Override |
| 90 | + public void doPost(HttpServletRequest request, HttpServletResponse response) |
| 91 | + throws ServletException, IOException { |
| 92 | + |
| 93 | + String error = null; |
| 94 | + PrintWriter pw = response.getWriter(); |
| 95 | + |
| 96 | + Weblog weblog = null; |
| 97 | + WeblogEntry entry = null; |
| 98 | + |
| 99 | + RollerMessages messages = new RollerMessages(); |
| 100 | + |
| 101 | + WeblogTrackbackRequest trackbackRequest = null; |
| 102 | + if (!WebloggerRuntimeConfig.getBooleanProperty("users.trackbacks.enabled")) { |
| 103 | + error = "Trackbacks are disabled for this site"; |
| 104 | + } else { |
| 105 | + |
| 106 | + try { |
| 107 | + trackbackRequest = new WeblogTrackbackRequest(request); |
| 108 | + |
| 109 | + if ((trackbackRequest.getTitle() == null) || |
| 110 | + "".equals(trackbackRequest.getTitle())) { |
| 111 | + trackbackRequest.setTitle(trackbackRequest.getUrl()); |
| 112 | + } |
| 113 | + |
| 114 | + if (trackbackRequest.getExcerpt() == null) { |
| 115 | + trackbackRequest.setExcerpt(""); |
| 116 | + } else if (trackbackRequest.getExcerpt().length() >= RollerConstants.TEXTWIDTH_255) { |
| 117 | + trackbackRequest.setExcerpt(trackbackRequest.getExcerpt().substring(0, |
| 118 | + RollerConstants.TEXTWIDTH_255 - 3)+"..."); |
| 119 | + } |
| 120 | + |
| 121 | + // lookup weblog specified by comment request |
| 122 | + weblog = WebloggerFactory.getWeblogger().getWeblogManager() |
| 123 | + .getWeblogByHandle(trackbackRequest.getWeblogHandle()); |
| 124 | + |
| 125 | + if (weblog == null) { |
| 126 | + throw new WebloggerException("unable to lookup weblog: "+ |
| 127 | + trackbackRequest.getWeblogHandle()); |
| 128 | + } |
| 129 | + |
| 130 | + // lookup entry specified by comment request |
| 131 | + WeblogEntryManager weblogMgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); |
| 132 | + entry = weblogMgr.getWeblogEntryByAnchor(weblog, trackbackRequest.getWeblogAnchor()); |
| 133 | + |
| 134 | + if (entry == null) { |
| 135 | + throw new WebloggerException("unable to lookup entry: "+ |
| 136 | + trackbackRequest.getWeblogAnchor()); |
| 137 | + } |
| 138 | + |
| 139 | + } catch (Exception e) { |
| 140 | + // some kind of error parsing the request or looking up weblog |
| 141 | + logger.debug("error creating trackback request", e); |
| 142 | + error = e.getMessage(); |
| 143 | + } |
| 144 | + } |
| 145 | + |
| 146 | + if (error != null) { |
| 147 | + return; |
| 148 | + } |
| 149 | + |
| 150 | + try { |
| 151 | + // check if trackbacks are allowed for this entry |
| 152 | + // this checks site-wide settings, weblog settings, and entry settings |
| 153 | + if (entry != null && entry.getCommentsStillAllowed() && entry.isPublished()) { |
| 154 | + |
| 155 | + // Track trackbacks as comments |
| 156 | + WeblogEntryComment comment = new WeblogEntryComment(); |
| 157 | + comment.setContent("[Trackback] "+trackbackRequest.getExcerpt()); |
| 158 | + comment.setName(trackbackRequest.getBlogName()); |
| 159 | + comment.setUrl(trackbackRequest.getUrl()); |
| 160 | + comment.setWeblogEntry(entry); |
| 161 | + comment.setRemoteHost(request.getRemoteHost()); |
| 162 | + comment.setNotify(Boolean.FALSE); |
| 163 | + comment.setPostTime(new Timestamp(new Date().getTime())); |
| 164 | + |
| 165 | + // run new trackback through validators |
| 166 | + int validationScore = commentValidationManager.validateComment(comment, messages); |
| 167 | + logger.debug("Comment Validation score: " + validationScore); |
| 168 | + |
| 169 | + if (validationScore == RollerConstants.PERCENT_100 && weblog.getCommentModerationRequired()) { |
| 170 | + // Valid comments go into moderation if required |
| 171 | + comment.setStatus(ApprovalStatus.PENDING); |
| 172 | + } else if (validationScore == RollerConstants.PERCENT_100) { |
| 173 | + // else they're approved |
| 174 | + comment.setStatus(ApprovalStatus.APPROVED); |
| 175 | + } else { |
| 176 | + // Invalid comments are marked as spam |
| 177 | + comment.setStatus(ApprovalStatus.SPAM); |
| 178 | + } |
| 179 | + |
| 180 | + // save, commit, send response |
| 181 | + if (!ApprovalStatus.SPAM.equals(comment.getStatus()) || |
| 182 | + !WebloggerRuntimeConfig.getBooleanProperty("trackbacks.ignoreSpam.enabled")) { |
| 183 | + |
| 184 | + WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); |
| 185 | + mgr.saveComment(comment); |
| 186 | + WebloggerFactory.getWeblogger().flush(); |
| 187 | + |
| 188 | + // only invalidate the cache if comment isn't moderated |
| 189 | + if(!weblog.getCommentModerationRequired()) { |
| 190 | + // Clear all caches associated with comment |
| 191 | + CacheManager.invalidate(comment); |
| 192 | + } |
| 193 | + |
| 194 | + // Send email notifications |
| 195 | + MailUtil.sendEmailNotification(comment, messages, |
| 196 | + I18nMessages.getMessages(trackbackRequest.getLocaleInstance()), |
| 197 | + validationScore == RollerConstants.PERCENT_100); |
| 198 | + |
| 199 | + if (ApprovalStatus.PENDING.equals(comment.getStatus())) { |
| 200 | + pw.println(this.getSuccessResponse("Trackback submitted to moderator")); |
| 201 | + } else { |
| 202 | + pw.println(this.getSuccessResponse("Trackback accepted")); |
| 203 | + } |
| 204 | + } |
| 205 | + |
| 206 | + } else if (entry!=null) { |
| 207 | + error = "Comments and Trackbacks are disabled for the entry specified."; |
| 208 | + } else { |
| 209 | + error = "Entry not specified."; |
| 210 | + } |
| 211 | + |
| 212 | + } catch (Exception e) { |
| 213 | + error = e.getMessage(); |
| 214 | + if ( error == null ) { |
| 215 | + error = e.getClass().getName(); |
| 216 | + } |
| 217 | + } |
| 218 | + |
| 219 | + if(error!= null) { |
| 220 | +} |
| 221 | + |
| 222 | + } |
| 223 | + |
| 224 | + |
| 225 | + private String getSuccessResponse(String message) { |
| 226 | + |
| 227 | + StringBuilder output = new StringBuilder(); |
| 228 | + |
| 229 | + output.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); |
| 230 | + output.append("<response>"); |
| 231 | + output.append("<error>0</error>"); |
| 232 | + output.append("<message>"); |
| 233 | + output.append(message); |
| 234 | + output.append("</message>"); |
| 235 | + output.append("</response>"); |
| 236 | + |
| 237 | + return output.toString(); |
| 238 | + } |
| 239 | + |
| 240 | + |
| 241 | + private String getErrorResponse(String message) { |
| 242 | + |
| 243 | + StringBuilder output = new StringBuilder(); |
| 244 | + |
| 245 | + output.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); |
| 246 | + output.append("<response>"); |
| 247 | + output.append("<error>1</error>"); |
| 248 | + output.append("<message>ERROR: "); |
| 249 | + output.append(message); |
| 250 | + output.append("</message>"); |
| 251 | + output.append("</response>"); |
| 252 | + |
| 253 | + return output.toString(); |
| 254 | + } |
| 255 | + |
| 256 | +} |
0 commit comments