1 31 package org.blojsom.plugin.trackback; 32 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 import org.blojsom.blog.Blog; 36 import org.blojsom.blog.Entry; 37 import org.blojsom.plugin.Plugin; 38 import org.blojsom.plugin.PluginException; 39 import org.blojsom.util.BlojsomConstants; 40 41 import javax.servlet.http.HttpServletRequest ; 42 import javax.servlet.http.HttpServletResponse ; 43 import java.io.BufferedReader ; 44 import java.io.IOException ; 45 import java.io.InputStreamReader ; 46 import java.net.HttpURLConnection ; 47 import java.net.URL ; 48 import java.net.URLEncoder ; 49 import java.util.Map ; 50 import java.util.regex.Matcher ; 51 import java.util.regex.Pattern ; 52 53 60 public class AutoTrackbackPlugin implements Plugin { 61 62 private Log _logger = LogFactory.getLog(AutoTrackbackPlugin.class); 63 64 private static final int REGEX_OPTIONS = Pattern.DOTALL | Pattern.MULTILINE | Pattern.CASE_INSENSITIVE; 65 private static final Pattern RDF_OUTER_PATTERN = Pattern.compile("(<rdf:RDF.*?</rdf:RDF>).*?", REGEX_OPTIONS); 66 private static final Pattern RDF_INNER_PATTERN = Pattern.compile("(<rdf:Description.*/>)", REGEX_OPTIONS); 67 private static final Pattern DC_IDENTIFIER_PATTERN = Pattern.compile("dc:identifier=\"(.*)\""); 68 private static final Pattern TRACKBACK_PING_PATTERN = Pattern.compile("trackback:ping=\"(.*)\""); 69 private static final Pattern HREF_PATTERN = Pattern.compile("<\\s*a.*?href\\s*=\\s*\"(([^\"]+).*?)\"\\s*>", REGEX_OPTIONS); 70 71 76 public void init() throws PluginException { 77 } 78 79 85 private void trackbackAutodiscovery(Blog blog, Entry blogEntry) { 86 try { 87 StringBuffer trackbackPingURLParameters = new StringBuffer (); 89 trackbackPingURLParameters.append("&").append(TrackbackPlugin.TRACKBACK_URL_PARAM).append("=").append(blogEntry.getId()); 90 trackbackPingURLParameters.append("&").append(TrackbackPlugin.TRACKBACK_TITLE_PARAM).append("=").append(URLEncoder.encode(blogEntry.getTitle(), BlojsomConstants.UTF8)); 91 trackbackPingURLParameters.append("&").append(TrackbackPlugin.TRACKBACK_BLOG_NAME_PARAM).append("=").append(URLEncoder.encode(blog.getBlogName(), BlojsomConstants.UTF8)); 92 93 String excerpt = blogEntry.getDescription().replaceAll("<.*?>", ""); 94 if (excerpt.length() > 255) { 95 excerpt = excerpt.substring(0, 251); 96 excerpt += "..."; 97 } 98 trackbackPingURLParameters.append("&").append(TrackbackPlugin.TRACKBACK_EXCERPT_PARAM).append("=").append(URLEncoder.encode(excerpt, BlojsomConstants.UTF8)); 99 100 Matcher hrefMatcher = HREF_PATTERN.matcher(blogEntry.getDescription()); 102 while (hrefMatcher.find()) { 103 104 if (hrefMatcher.groupCount() == 2) { 107 String hyperlink = hrefMatcher.group(1); 108 if (_logger.isDebugEnabled()) { 109 _logger.debug("Found hyperlink: " + hyperlink); 110 } 111 BufferedReader br; 112 URL hyperlinkURL = new URL (hyperlink); 113 br = new BufferedReader (new InputStreamReader (hyperlinkURL.openStream())); 114 String html; 115 StringBuffer contents = new StringBuffer (); 116 while ((html = br.readLine()) != null) { 117 contents.append(html).append("\n"); 118 } 119 120 Matcher rdfOuterMatcher = RDF_OUTER_PATTERN.matcher(contents.toString()); 122 while (rdfOuterMatcher.find()) { 123 if (_logger.isDebugEnabled()) { 124 _logger.debug("Found outer RDF text in hyperlink"); 125 } 126 for (int i = 0; i < rdfOuterMatcher.groupCount(); i++) { 127 String outerRdfText = rdfOuterMatcher.group(i); 128 129 Matcher rdfInnerMatcher = RDF_INNER_PATTERN.matcher(outerRdfText); 131 while (rdfInnerMatcher.find()) { 132 if (_logger.isDebugEnabled()) { 133 _logger.debug("Found inner RDF text in hyperlink"); 134 } 135 for (int j = 0; j < rdfInnerMatcher.groupCount(); j++) { 136 String innerRdfText = rdfInnerMatcher.group(j); 137 138 Matcher dcIdentifierMatcher = DC_IDENTIFIER_PATTERN.matcher(innerRdfText); 140 if (dcIdentifierMatcher.find()) { 141 String dcIdentifier = dcIdentifierMatcher.group(1); 142 143 if (dcIdentifier.equals(hyperlink)) { 145 if (_logger.isDebugEnabled()) { 146 _logger.debug("Matched dc:identifier to hyperlink"); 147 } 148 Matcher trackbackPingMatcher = TRACKBACK_PING_PATTERN.matcher(innerRdfText); 149 if (trackbackPingMatcher.find()) { 150 StringBuffer trackbackPingURL = new StringBuffer (trackbackPingMatcher.group(1)); 151 152 if (_logger.isDebugEnabled()) { 153 _logger.debug("Automatically sending trackback ping to URL: " + trackbackPingURL.toString()); 154 } 155 URL trackbackUrl = new URL (trackbackPingURL.toString()); 156 157 HttpURLConnection trackbackUrlConnection = (HttpURLConnection ) trackbackUrl.openConnection(); 159 trackbackUrlConnection.setRequestMethod("POST"); 160 trackbackUrlConnection.setRequestProperty("Content-Encoding", BlojsomConstants.UTF8); 161 trackbackUrlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 162 trackbackUrlConnection.setRequestProperty("Content-Length", "" + trackbackPingURLParameters.length()); 163 trackbackUrlConnection.setDoOutput(true); 164 trackbackUrlConnection.getOutputStream().write(trackbackPingURLParameters.toString().getBytes(BlojsomConstants.UTF8)); 165 trackbackUrlConnection.connect(); 166 BufferedReader trackbackStatus = new BufferedReader (new InputStreamReader (trackbackUrlConnection.getInputStream())); 167 String line; 168 StringBuffer status = new StringBuffer (); 169 while ((line = trackbackStatus.readLine()) != null) { 170 status.append(line).append("\n"); 171 } 172 } 173 } 174 } 175 } 176 } 177 } 178 } 179 } 180 } 181 } catch (IOException e) { 182 if (_logger.isErrorEnabled()) { 183 _logger.error(e); 184 } 185 } 186 } 187 188 199 public Entry[] process(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Blog blog, Map context, Entry[] entries) throws PluginException { 200 for (int i = 0; i < entries.length; i++) { 201 Entry entry = entries[i]; 202 if (entry.getMetaData() != null) { 203 Map entryMetaData = entry.getMetaData(); 204 if (entryMetaData.containsKey("auto-trackback") && !entryMetaData.containsKey("auto-trackback-complete")) { 205 trackbackAutodiscovery(blog, entry); 206 entryMetaData.put("auto-trackback-complete", "true"); 207 } 208 } else { 209 _logger.debug("Skipping blog entry for autotrackback: " + entry.getId()); 210 } 211 } 212 213 return entries; 214 } 215 216 221 public void cleanup() throws PluginException { 222 } 223 224 229 public void destroy() throws PluginException { 230 } 231 } 232 | Popular Tags |