| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. The ASF licenses this file to You |
| * under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. For additional information regarding |
| * copyright in this work, please see the NOTICE file in the top level |
| * directory of this distribution. |
| */ |
| |
| package org.apache.roller.weblogger.ui.rendering.servlets; |
| |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.sql.Timestamp; |
| import java.util.Date; |
| import javax.servlet.ServletConfig; |
| import javax.servlet.ServletException; |
| import javax.servlet.http.HttpServlet; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.roller.util.RollerConstants; |
| import org.apache.roller.weblogger.WebloggerException; |
| import org.apache.roller.weblogger.config.WebloggerRuntimeConfig; |
| import org.apache.roller.weblogger.business.WebloggerFactory; |
| import org.apache.roller.weblogger.business.WeblogEntryManager; |
| import org.apache.roller.weblogger.pojos.WeblogEntryComment; |
| import org.apache.roller.weblogger.pojos.WeblogEntryComment.ApprovalStatus; |
| import org.apache.roller.weblogger.pojos.WeblogEntry; |
| import org.apache.roller.weblogger.pojos.Weblog; |
| import org.apache.roller.weblogger.ui.rendering.plugins.comments.CommentValidationManager; |
| import org.apache.roller.weblogger.ui.rendering.plugins.comments.TrackbackLinkbackCommentValidator; |
| import org.apache.roller.weblogger.ui.rendering.util.WeblogTrackbackRequest; |
| import org.apache.roller.weblogger.util.I18nMessages; |
| import org.apache.roller.weblogger.util.MailUtil; |
| import org.apache.roller.weblogger.util.RollerMessages; |
| import org.apache.roller.weblogger.util.cache.CacheManager; |
| |
| |
| /** |
| * Roller's Trackback server implementation. POSTing to this Servlet will add a |
| * Trackback to a Weblog Entry. For more info on Trackback, read the spec: |
| * <a href="http://www.movabletype.org/documentation/trackback/specification.html">MT Trackback</a>. |
| */ |
| public class TrackbackServlet extends HttpServlet { |
| |
| private static Log logger = LogFactory.getLog(TrackbackServlet.class); |
| |
| private CommentValidationManager commentValidationManager = null; |
| |
| |
| @Override |
| public void init(ServletConfig config) throws ServletException { |
| commentValidationManager = new CommentValidationManager(); |
| |
| // add trackback verification validator just for trackbacks |
| commentValidationManager.addCommentValidator(new TrackbackLinkbackCommentValidator()); |
| } |
| |
| |
| /** |
| * Handle incoming http GET requests. |
| * |
| * The TrackbackServlet does not support GET requests, it's a 404. |
| */ |
| @Override |
| public void doGet(HttpServletRequest request, HttpServletResponse response) |
| throws IOException, ServletException { |
| |
| response.sendError(HttpServletResponse.SC_NOT_FOUND); |
| } |
| |
| |
| /** |
| * Service incoming POST requests. |
| * |
| * Here we handle incoming trackback posts. |
| */ |
| @Override |
| public void doPost(HttpServletRequest request, HttpServletResponse response) |
| throws ServletException, IOException { |
| |
| String error = null; |
| PrintWriter pw = response.getWriter(); |
| |
| Weblog weblog = null; |
| WeblogEntry entry = null; |
| |
| RollerMessages messages = new RollerMessages(); |
| |
| WeblogTrackbackRequest trackbackRequest = null; |
| if (!WebloggerRuntimeConfig.getBooleanProperty("users.trackbacks.enabled")) { |
| error = "Trackbacks are disabled for this site"; |
| } else { |
| |
| try { |
| trackbackRequest = new WeblogTrackbackRequest(request); |
| |
| if ((trackbackRequest.getTitle() == null) || |
| "".equals(trackbackRequest.getTitle())) { |
| trackbackRequest.setTitle(trackbackRequest.getUrl()); |
| } |
| |
| if (trackbackRequest.getExcerpt() == null) { |
| trackbackRequest.setExcerpt(""); |
| } else if (trackbackRequest.getExcerpt().length() >= RollerConstants.TEXTWIDTH_255) { |
| trackbackRequest.setExcerpt(trackbackRequest.getExcerpt().substring(0, |
| RollerConstants.TEXTWIDTH_255 - 3)+"..."); |
| } |
| |
| // lookup weblog specified by comment request |
| weblog = WebloggerFactory.getWeblogger().getWeblogManager() |
| .getWeblogByHandle(trackbackRequest.getWeblogHandle()); |
| |
| if (weblog == null) { |
| throw new WebloggerException("unable to lookup weblog: "+ |
| trackbackRequest.getWeblogHandle()); |
| } |
| |
| // lookup entry specified by comment request |
| WeblogEntryManager weblogMgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); |
| entry = weblogMgr.getWeblogEntryByAnchor(weblog, trackbackRequest.getWeblogAnchor()); |
| |
| if (entry == null) { |
| throw new WebloggerException("unable to lookup entry: "+ |
| trackbackRequest.getWeblogAnchor()); |
| } |
| |
| } catch (Exception e) { |
| // some kind of error parsing the request or looking up weblog |
| logger.debug("error creating trackback request", e); |
| error = e.getMessage(); |
| } |
| } |
| |
| if (error != null) { |
| pw.println(this.getErrorResponse(error)); |
| return; |
| } |
| |
| try { |
| // check if trackbacks are allowed for this entry |
| // this checks site-wide settings, weblog settings, and entry settings |
| if (entry != null && entry.getCommentsStillAllowed() && entry.isPublished()) { |
| |
| // Track trackbacks as comments |
| WeblogEntryComment comment = new WeblogEntryComment(); |
| comment.setContent("[Trackback] "+trackbackRequest.getExcerpt()); |
| comment.setName(trackbackRequest.getBlogName()); |
| comment.setUrl(trackbackRequest.getUrl()); |
| comment.setWeblogEntry(entry); |
| comment.setRemoteHost(request.getRemoteHost()); |
| comment.setNotify(Boolean.FALSE); |
| comment.setPostTime(new Timestamp(new Date().getTime())); |
| |
| // run new trackback through validators |
| int validationScore = commentValidationManager.validateComment(comment, messages); |
| logger.debug("Comment Validation score: " + validationScore); |
| |
| if (validationScore == RollerConstants.PERCENT_100 && weblog.getCommentModerationRequired()) { |
| // Valid comments go into moderation if required |
| comment.setStatus(ApprovalStatus.PENDING); |
| } else if (validationScore == RollerConstants.PERCENT_100) { |
| // else they're approved |
| comment.setStatus(ApprovalStatus.APPROVED); |
| } else { |
| // Invalid comments are marked as spam |
| comment.setStatus(ApprovalStatus.SPAM); |
| } |
| |
| // save, commit, send response |
| if (!ApprovalStatus.SPAM.equals(comment.getStatus()) || |
| !WebloggerRuntimeConfig.getBooleanProperty("trackbacks.ignoreSpam.enabled")) { |
| |
| WeblogEntryManager mgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); |
| mgr.saveComment(comment); |
| WebloggerFactory.getWeblogger().flush(); |
| |
| // only invalidate the cache if comment isn't moderated |
| if(!weblog.getCommentModerationRequired()) { |
| // Clear all caches associated with comment |
| CacheManager.invalidate(comment); |
| } |
| |
| // Send email notifications |
| MailUtil.sendEmailNotification(comment, messages, |
| I18nMessages.getMessages(trackbackRequest.getLocaleInstance()), |
| validationScore == RollerConstants.PERCENT_100); |
| |
| if (ApprovalStatus.PENDING.equals(comment.getStatus())) { |
| pw.println(this.getSuccessResponse("Trackback submitted to moderator")); |
| } else { |
| pw.println(this.getSuccessResponse("Trackback accepted")); |
| } |
| } |
| |
| } else if (entry!=null) { |
| error = "Comments and Trackbacks are disabled for the entry specified."; |
| } else { |
| error = "Entry not specified."; |
| } |
| |
| } catch (Exception e) { |
| error = e.getMessage(); |
| if ( error == null ) { |
| error = e.getClass().getName(); |
| } |
| } |
| |
| if(error!= null) { |
| pw.println(this.getErrorResponse(error)); |
| } |
| |
| } |
| |
| |
| private String getSuccessResponse(String message) { |
| |
| StringBuilder output = new StringBuilder(); |
| |
| output.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); |
| output.append("<response>"); |
| output.append("<error>0</error>"); |
| output.append("<message>"); |
| output.append(message); |
| output.append("</message>"); |
| output.append("</response>"); |
| |
| return output.toString(); |
| } |
| |
| |
| private String getErrorResponse(String message) { |
| |
| StringBuilder output = new StringBuilder(); |
| |
| output.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); |
| output.append("<response>"); |
| output.append("<error>1</error>"); |
| output.append("<message>ERROR: "); |
| output.append(message); |
| output.append("</message>"); |
| output.append("</response>"); |
| |
| return output.toString(); |
| } |
| |
| } |