Package org.apache.roller.weblogger.business.plugins.entry

Source Code of org.apache.roller.weblogger.business.plugins.entry.BookmarkPlugin

/*
* 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.business.plugins.entry;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.business.BookmarkManager;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.business.plugins.entry.WeblogEntryPlugin;
import org.apache.roller.weblogger.pojos.WeblogBookmark;
import org.apache.roller.weblogger.pojos.WeblogBookmarkFolder;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.apache.roller.weblogger.pojos.Weblog;


/**
* Automatically insert links into entry text based on users bookmarks.
*/
public class BookmarkPlugin implements WeblogEntryPlugin {
   
    private static Log mLogger = LogFactory.getLog(BookmarkPlugin.class);
   
    protected String name = "Bookmark Linker";
    protected String description = "Automatically uses your Bookmarks to " +
            "create links.  Simply use the Name of a Bookmark and it will be " +
            "converted into a hyperlink using the Bookmark's URL.";
   
   
    public BookmarkPlugin() {
        mLogger.debug("BookmarkPlugin instantiated.");
    }
   
   
    public String getName() {
        return name;
    }
   
   
    public String getDescription() {
        return StringEscapeUtils.escapeJavaScript(description);
    }
   
   
    public void init(Weblog website) throws WebloggerException {}
   
   
    public String render(WeblogEntry entry, String str) {
        String text = str;
        try {
            BookmarkManager bMgr = WebloggerFactory.getWeblogger().getBookmarkManager();
            WeblogBookmarkFolder rootFolder = bMgr.getRootFolder(entry.getWebsite());
            text = matchBookmarks(text, rootFolder);
            text = lookInFolders(text, rootFolder.getFolders());
        } catch (WebloggerException e) {
            // nothing much I can do, go with default "Weblog" value
            // could be WebloggerException or NullPointerException
            mLogger.warn(e);
        }
        return text;
    }
   
   
    /**
     * Recursively travel down Folder tree, attempting
     * to match up Bookmarks in each Folder.
     *
     * @param text
     * @param folders
     * @return
     */
    private String lookInFolders(String text, Collection folders) {
       
        Iterator it = folders.iterator();
        while (it.hasNext()) {
            WeblogBookmarkFolder folder = (WeblogBookmarkFolder)it.next();
            text = matchBookmarks(text, folder);
           
            if (!folder.getFolders().isEmpty()) {
                lookInFolders(text, folder.getFolders());
            }
        }
       
        return text;
    }
   
   
    private String matchBookmarks(String text,WeblogBookmarkFolder folder) {
        Iterator bookmarks = folder.getBookmarks().iterator();
        String workingText = text;
        while (bookmarks.hasNext()) {
            WeblogBookmark bookmark = (WeblogBookmark)bookmarks.next();
            String bkDescription = bookmark.getDescription();
            if (bkDescription == null) bkDescription = "";
            String bookmarkLink = "<a href=\"" +
                    bookmark.getUrl() + "\" title=\"" +
                    bkDescription + "\">" +
                    bookmark.getName() + "</a>";
            try {
                // Replace all occurrences of bookmark name that don't occur within the bounds of an anchor tag
                // Notes:
                // - use reluctant quantifiers on the tags to avoid gobbling more than desired
                // - use non-capturing groups for boundaries to avoid replacing the boundary as well as the bookmark name.
                // - we depend on the numbering of the specific groups in this expression in the replacement code below.
                // TODO: should escape the bookmark name
                String regEx = "(<a(?:\\s.*?)??/>)|(<a(?:\\s.*?)??>)|(</a(?:\\s.*?)??>)|(?:\\b)(" + bookmark.getName() + ")(?:\\b)";
                Matcher m = Pattern.compile(regEx).matcher(workingText);
                StringBuffer textBuf = new StringBuffer(workingText.length());
                int inLink = 0;
                while (m.find()) {
                    if (m.group(1) != null) {
                        // self-closed anchor tag <a  ... /> -- ignore
                    } else if (m.group(2) != null) {
                        // matched opening anchor tag <a ...>
                        inLink++;
                    } else if (m.group(3) != null) {
                        // closing anchor tag </a>, but ignore nonmatching ones
                        if (inLink > 0) inLink--;
                    } else if (m.group(4) != null) {
                        // matched the bookmark -- replace, but only if not within a link tag.
                        if (inLink == 0) m.appendReplacement(textBuf, bookmarkLink);
                    }
                    // Any remaining case indicates a bug.  One could add an else with assertion here.  Conservatively don't substitute.
                }
                m.appendTail(textBuf);
                workingText = textBuf.toString();
            } catch (PatternSyntaxException e) {
                // Can happen since we don't escape pattern the bookmark name to protect pattern characters.
                mLogger.warn("Failed to substitute for bookmark [" + bookmark.getName() + "] due to regular expression characters.");
            }
        }
        return workingText.toString();
    }
   
}
TOP

Related Classes of org.apache.roller.weblogger.business.plugins.entry.BookmarkPlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.