KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > ui > rendering > plugins > BookmarkPlugin


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.ui.rendering.plugins;
20
21 import java.util.Collection JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.regex.Matcher JavaDoc;
25 import java.util.regex.Pattern JavaDoc;
26 import java.util.regex.PatternSyntaxException JavaDoc;
27 import org.apache.commons.lang.StringEscapeUtils;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.roller.RollerException;
31 import org.apache.roller.model.BookmarkManager;
32 import org.apache.roller.model.RollerFactory;
33 import org.apache.roller.model.WeblogEntryPlugin;
34 import org.apache.roller.pojos.BookmarkData;
35 import org.apache.roller.pojos.FolderData;
36 import org.apache.roller.pojos.WeblogEntryData;
37 import org.apache.roller.pojos.WebsiteData;
38
39
40 /**
41  * Automatically insert links into entry text based on users bookmarks.
42  */

43 public class BookmarkPlugin implements WeblogEntryPlugin {
44     
45     private static Log mLogger = LogFactory.getLog(BookmarkPlugin.class);
46     
47     protected String JavaDoc name = "Bookmark Linker";
48     protected String JavaDoc description = "Automatically uses your Bookmarks to " +
49             "create links. Simply use the Name of a Bookmark and it will be " +
50             "converted into a hyperlink using the Bookmark's URL.";
51     
52     
53     public BookmarkPlugin() {
54         mLogger.debug("BookmarkPlugin instantiated.");
55     }
56     
57     
58     public String JavaDoc getName() {
59         return name;
60     }
61     
62     
63     public String JavaDoc getDescription() {
64         return StringEscapeUtils.escapeJavaScript(description);
65     }
66     
67     
68     public void init(WebsiteData website) throws RollerException {}
69     
70     
71     public String JavaDoc render(WeblogEntryData entry, String JavaDoc str) {
72         String JavaDoc text = str;
73         try {
74             BookmarkManager bMgr = RollerFactory.getRoller().getBookmarkManager();
75             FolderData rootFolder = bMgr.getRootFolder(entry.getWebsite());
76             text = matchBookmarks(text, rootFolder);
77             text = lookInFolders(text, rootFolder.getFolders());
78         } catch (RollerException e) {
79             // nothing much I can do, go with default "Weblog" value
80
// could be RollerException or NullPointerException
81
mLogger.warn(e);
82         }
83         return text;
84     }
85     
86     
87     /**
88      * Recursively travel down Folder tree, attempting
89      * to match up Bookmarks in each Folder.
90      *
91      * @param text
92      * @param folders
93      * @return
94      */

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