KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > blojsom > plugin > trackback > AutoTrackbackPlugin


1 /**
2  * Copyright (c) 2003-2006, David A. Czarnecki
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * Redistributions of source code must retain the above copyright notice, this list of conditions and the
9  * following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
11  * following disclaimer in the documentation and/or other materials provided with the distribution.
12  * Neither the name of "David A. Czarnecki" and "blojsom" nor the names of its contributors may be used to
13  * endorse or promote products derived from this software without specific prior written permission.
14  * Products derived from this software may not be called "blojsom", nor may "blojsom" appear in their name,
15  * without prior written permission of David A. Czarnecki.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
18  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21  * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */

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 JavaDoc;
42 import javax.servlet.http.HttpServletResponse JavaDoc;
43 import java.io.BufferedReader JavaDoc;
44 import java.io.IOException JavaDoc;
45 import java.io.InputStreamReader JavaDoc;
46 import java.net.HttpURLConnection JavaDoc;
47 import java.net.URL JavaDoc;
48 import java.net.URLEncoder JavaDoc;
49 import java.util.Map JavaDoc;
50 import java.util.regex.Matcher JavaDoc;
51 import java.util.regex.Pattern JavaDoc;
52
53 /**
54  * AutoTrackbackPlugin
55  *
56  * @author David Czarnecki
57  * @since blojsom 3.0
58  * @version $Id: AutoTrackbackPlugin.java,v 1.2 2006/03/20 22:51:08 czarneckid Exp $
59  */

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 JavaDoc RDF_OUTER_PATTERN = Pattern.compile("(<rdf:RDF.*?</rdf:RDF>).*?", REGEX_OPTIONS);
66     private static final Pattern JavaDoc RDF_INNER_PATTERN = Pattern.compile("(<rdf:Description.*/>)", REGEX_OPTIONS);
67     private static final Pattern JavaDoc DC_IDENTIFIER_PATTERN = Pattern.compile("dc:identifier=\"(.*)\"");
68     private static final Pattern JavaDoc TRACKBACK_PING_PATTERN = Pattern.compile("trackback:ping=\"(.*)\"");
69     private static final Pattern JavaDoc HREF_PATTERN = Pattern.compile("<\\s*a.*?href\\s*=\\s*\"(([^\"]+).*?)\"\\s*>", REGEX_OPTIONS);
70
71     /**
72      * Initialize this plugin. This method only called when the plugin is instantiated.
73      *
74      * @throws org.blojsom.plugin.PluginException If there is an error initializing the plugin
75      */

76     public void init() throws PluginException {
77     }
78
79     /**
80      * Perform the trackback autodiscovery process
81      *
82      * @param blog Blog information
83      * @param blogEntry Blog entry
84      */

85     private void trackbackAutodiscovery(Blog blog, Entry blogEntry) {
86         try {
87             // Build the URL parameters for the trackback ping URL
88
StringBuffer JavaDoc trackbackPingURLParameters = new StringBuffer JavaDoc();
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 JavaDoc 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             // Extract all the HREF links from the blog description
101
Matcher JavaDoc hrefMatcher = HREF_PATTERN.matcher(blogEntry.getDescription());
102             while (hrefMatcher.find()) {
103
104                 // If we have a group count of 2, the inner group will be the http:// reference
105
// Read the entire contents of the URL into a buffer
106
if (hrefMatcher.groupCount() == 2) {
107                     String JavaDoc hyperlink = hrefMatcher.group(1);
108                     if (_logger.isDebugEnabled()) {
109                         _logger.debug("Found hyperlink: " + hyperlink);
110                     }
111                     BufferedReader JavaDoc br;
112                     URL JavaDoc hyperlinkURL = new URL JavaDoc(hyperlink);
113                     br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(hyperlinkURL.openStream()));
114                     String JavaDoc html;
115                     StringBuffer JavaDoc contents = new StringBuffer JavaDoc();
116                     while ((html = br.readLine()) != null) {
117                         contents.append(html).append("\n");
118                     }
119
120                     // Look for the Auto Trackback RDF in the HTML
121
Matcher JavaDoc 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 JavaDoc outerRdfText = rdfOuterMatcher.group(i);
128
129                             // Look for the inner RDF description
130
Matcher JavaDoc 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 JavaDoc innerRdfText = rdfInnerMatcher.group(j);
137
138                                     // Look for a dc:identifier attribute which matches the current hyperlink
139
Matcher JavaDoc dcIdentifierMatcher = DC_IDENTIFIER_PATTERN.matcher(innerRdfText);
140                                     if (dcIdentifierMatcher.find()) {
141                                         String JavaDoc dcIdentifier = dcIdentifierMatcher.group(1);
142
143                                         // If we find a match, send a trackback ping to the
144
if (dcIdentifier.equals(hyperlink)) {
145                                             if (_logger.isDebugEnabled()) {
146                                                 _logger.debug("Matched dc:identifier to hyperlink");
147                                             }
148                                             Matcher JavaDoc trackbackPingMatcher = TRACKBACK_PING_PATTERN.matcher(innerRdfText);
149                                             if (trackbackPingMatcher.find()) {
150                                                 StringBuffer JavaDoc trackbackPingURL = new StringBuffer JavaDoc(trackbackPingMatcher.group(1));
151
152                                                 if (_logger.isDebugEnabled()) {
153                                                     _logger.debug("Automatically sending trackback ping to URL: " + trackbackPingURL.toString());
154                                                 }
155                                                 URL JavaDoc trackbackUrl = new URL JavaDoc(trackbackPingURL.toString());
156
157                                                 // Open a connection to the trackback URL and read its input
158
HttpURLConnection JavaDoc trackbackUrlConnection = (HttpURLConnection JavaDoc) 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 JavaDoc trackbackStatus = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(trackbackUrlConnection.getInputStream()));
167                                                 String JavaDoc line;
168                                                 StringBuffer JavaDoc status = new StringBuffer JavaDoc();
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 JavaDoc e) {
182             if (_logger.isErrorEnabled()) {
183                 _logger.error(e);
184             }
185         }
186     }
187
188     /**
189      * Process the blog entries
190      *
191      * @param httpServletRequest Request
192      * @param httpServletResponse Response
193      * @param blog {@link Blog} instance
194      * @param context Context
195      * @param entries Blog entries retrieved for the particular request
196      * @return Modified set of blog entries
197      * @throws PluginException If there is an error processing the blog entries
198      */

199     public Entry[] process(HttpServletRequest JavaDoc httpServletRequest, HttpServletResponse JavaDoc httpServletResponse, Blog blog, Map JavaDoc 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 JavaDoc 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     /**
217      * Perform any cleanup for the plugin. Called after {@link #process}.
218      *
219      * @throws PluginException If there is an error performing cleanup for this plugin
220      */

221     public void cleanup() throws PluginException {
222     }
223
224     /**
225      * Called when BlojsomServlet is taken out of service
226      *
227      * @throws PluginException If there is an error in finalizing this plugin
228      */

229     public void destroy() throws PluginException {
230     }
231 }
232
Popular Tags