KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > roller > presentation > velocity > plugins > bookmarks > BookmarkPlugin


1 /*
2  * Created on Nov 2, 2003
3  *
4  */

5 package org.roller.presentation.velocity.plugins.bookmarks;
6
7 import org.apache.commons.lang.StringEscapeUtils;
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.apache.velocity.context.Context;
11 import org.roller.RollerException;
12 import org.roller.model.BookmarkManager;
13 import org.roller.model.RollerFactory;
14 import org.roller.pojos.BookmarkData;
15 import org.roller.pojos.FolderData;
16 import org.roller.pojos.WeblogEntryData;
17 import org.roller.presentation.RollerRequest;
18 import org.roller.presentation.velocity.PagePlugin;
19 import java.util.regex.PatternSyntaxException JavaDoc;
20 import java.util.regex.Matcher JavaDoc;
21 import java.util.regex.Pattern JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24
25 /**
26  * @author lance
27  * @author Anil Gangolli (significant modifications)
28  */

29 public class BookmarkPlugin implements PagePlugin
30 {
31     protected String JavaDoc name = "Bookmark Linker";
32     protected String JavaDoc description = "Automatically uses your Bookmarks to " +
33         "create links. Simply use the Name of a Bookmark and it will be " +
34         "converted into a hyperlink using the Bookmark's URL.";
35
36     private static Log mLogger =
37        LogFactory.getFactory().getInstance(BookmarkPlugin.class);
38
39     public BookmarkPlugin()
40     {
41         mLogger.debug("BookmarkPlugin instantiated.");
42     }
43
44     public String JavaDoc toString() { return name; }
45
46     /* (non-Javadoc)
47      * @see org.roller.presentation.velocity.PagePlugin#init(org.roller.presentation.RollerRequest, org.apache.velocity.context.Context)
48      */

49     public void init(RollerRequest rreq, Context ctx) throws RollerException
50     {
51     }
52
53     /*
54      * Without Website cannot lookup Folders & Bookmarks
55      * (non-Javadoc)
56      * @see org.roller.presentation.velocity.PagePlugin#render(java.lang.String)
57      */

58     public String JavaDoc render(String JavaDoc text)
59     {
60         return text;
61     }
62
63     public String JavaDoc render(WeblogEntryData entry, boolean skipFlag)
64     {
65         String JavaDoc text = entry.getText();
66         try
67         {
68             BookmarkManager bMgr = RollerFactory.getRoller().getBookmarkManager();
69             FolderData rootFolder = bMgr.getRootFolder(entry.getWebsite());
70             text = matchBookmarks(text, rootFolder);
71             text = lookInFolders(text, rootFolder.getFolders());
72         }
73         catch (RollerException e)
74         {
75             // nothing much I can do, go with default "Weblog" value
76
// could be RollerException or NullPointerException
77
mLogger.warn(e);
78         }
79         return text;
80     }
81
82     /**
83      * Recursively travel down Folder tree, attempting
84      * to match up Bookmarks in each Folder.
85      *
86      * @param text
87      * @param folders
88      * @return
89      */

90     private String JavaDoc lookInFolders(String JavaDoc text, Collection JavaDoc folders)
91     {
92         Iterator JavaDoc it = folders.iterator();
93         while (it.hasNext())
94         {
95             FolderData folder = (FolderData)it.next();
96             text = matchBookmarks(text, folder);
97
98             try
99             {
100                 if (!folder.getFolders().isEmpty())
101                 {
102                     lookInFolders(text, folder.getFolders());
103                 }
104             }
105             catch (RollerException e)
106             {
107                 mLogger.error("Error getting child Folders");
108             }
109         }
110         return text;
111     }
112
113     private String JavaDoc matchBookmarks(String JavaDoc text, FolderData folder)
114     {
115         Iterator JavaDoc bookmarks = folder.getBookmarks().iterator();
116         String JavaDoc workingText = text;
117         while (bookmarks.hasNext())
118         {
119             BookmarkData bookmark = (BookmarkData)bookmarks.next();
120             String JavaDoc bkDescription = bookmark.getDescription();
121             if (bkDescription == null) bkDescription = "";
122             String JavaDoc bookmarkLink = "<a HREF=\"" +
123                 bookmark.getUrl() + "\" title=\"" +
124                 bkDescription + "\">" +
125                 bookmark.getName() + "</a>";
126             try
127             {
128                 // Replace all occurrences of bookmark name that don't occur within the bounds of an anchor tag
129
// Notes:
130
// - use reluctant quantifiers on the tags to avoid gobbling more than desired
131
// - use non-capturing groups for boundaries to avoid replacing the boundary as well as the bookmark name.
132
// - we depend on the numbering of the specific groups in this expression in the replacement code below.
133
// TODO: should escape the bookmark name
134
String JavaDoc regEx = "(<a(?:\\s.*?)??/>)|(<a(?:\\s.*?)??>)|(</a(?:\\s.*?)??>)|(?:\\b)(" + bookmark.getName() + ")(?:\\b)";
135                 Matcher JavaDoc m = Pattern.compile(regEx).matcher(workingText);
136                 StringBuffer JavaDoc textBuf = new StringBuffer JavaDoc(workingText.length());
137                 int inLink = 0;
138                 while (m.find())
139                 {
140                     if (m.group(1) != null)
141                     {
142                         // self-closed anchor tag <a ... /> -- ignore
143
}
144                     else if (m.group(2) != null)
145                     {
146                         // matched opening anchor tag <a ...>
147
inLink++;
148                     }
149                     else if (m.group(3) != null)
150                     {
151                         // closing anchor tag </a>, but ignore nonmatching ones
152
if (inLink > 0) inLink--;
153                     }
154                     else if (m.group(4) != null)
155                     {
156                         // matched the bookmark -- replace, but only if not within a link tag.
157
if (inLink == 0) m.appendReplacement(textBuf, bookmarkLink);
158                     }
159                     // Any remaining case indicates a bug. One could add an else with assertion here. Conservatively don't substitute.
160
}
161                 m.appendTail(textBuf);
162                 workingText = textBuf.toString();
163             }
164             catch (PatternSyntaxException JavaDoc e)
165             {
166                 // Can happen since we don't escape pattern the bookmark name to protect pattern characters.
167
mLogger.warn("Failed to substitute for bookmark [" + bookmark.getName() + "] due to regular expression characters.");
168             }
169         }
170         return workingText.toString();
171     }
172
173     public String JavaDoc getName() { return name; }
174     public String JavaDoc getDescription() { return StringEscapeUtils.escapeJavaScript(description); }
175 }
176
Popular Tags