001    /* 
002        Licensed to the Apache Software Foundation (ASF) under one
003        or more contributor license agreements.  See the NOTICE file
004        distributed with this work for additional information
005        regarding copyright ownership.  The ASF licenses this file
006        to you under the Apache License, Version 2.0 (the
007        "License"); you may not use this file except in compliance
008        with the License.  You may obtain a copy of the License at
009    
010           http://www.apache.org/licenses/LICENSE-2.0
011    
012        Unless required by applicable law or agreed to in writing,
013        software distributed under the License is distributed on an
014        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015        KIND, either express or implied.  See the License for the
016        specific language governing permissions and limitations
017        under the License.  
018     */
019    package org.apache.wiki.plugin;
020    
021    import java.text.SimpleDateFormat;
022    import java.util.*;
023    
024    import org.apache.log4j.Logger;
025    import org.apache.wiki.*;
026    import org.apache.wiki.api.exceptions.PluginException;
027    import org.apache.wiki.api.exceptions.ProviderException;
028    import org.apache.wiki.api.plugin.WikiPlugin;
029    import org.apache.wiki.preferences.Preferences;
030    
031    /**
032     * Builds a simple weblog.
033     * <p/>
034     * <p>Parameters : </p>
035     * <ul>
036     * <li><b>entrytext</b> - text of the link </li>
037     * <li><b>page</b> - if set, the entry is added to the named blog page. The default is the current page. </li>
038     * </ul>
039     *
040     * @since 1.9.21
041     */
042    public class WeblogEntryPlugin implements WikiPlugin {
043        private static Logger log = Logger.getLogger(WeblogEntryPlugin.class);
044    
045        private static final int MAX_BLOG_ENTRIES = 10000; // Just a precaution.
046    
047        /**
048         * Parameter name for setting the entrytext  Value is <tt>{@value}</tt>.
049         */
050        public static final String PARAM_ENTRYTEXT = "entrytext";
051        /**
052         * Optional parameter: page that actually contains the blog.
053         * This lets us provide a "new entry" link for a blog page 
054         * somewhere else than on the page itself.
055         */
056        // "page" for uniform naming with WeblogPlugin...
057        /**
058         * Parameter name for setting the page Value is <tt>{@value}</tt>.
059         */
060        public static final String PARAM_BLOGNAME = "page";
061    
062        /**
063         * Returns a new page name for entries.  It goes through the list of
064         * all blog pages, and finds out the next in line.
065         *
066         * @param engine   A WikiEngine
067         * @param blogName The page (or blog) name.
068         * @return A new name.
069         * @throws ProviderException If something goes wrong.
070         */
071        public String getNewEntryPage(WikiEngine engine, String blogName)
072                throws ProviderException {
073            SimpleDateFormat fmt = new SimpleDateFormat(WeblogPlugin.DEFAULT_DATEFORMAT);
074            String today = fmt.format(new Date());
075    
076            int entryNum = findFreeEntry(engine.getPageManager(),
077                    blogName,
078                    today);
079    
080    
081            String blogPage = WeblogPlugin.makeEntryPage(blogName,
082                    today,
083                    "" + entryNum);
084    
085            return blogPage;
086        }
087    
088        /**
089         * {@inheritDoc}
090         */
091        public String execute(WikiContext context, Map<String, String> params)
092                throws PluginException {
093            ResourceBundle rb = Preferences.getBundle(context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
094    
095            String weblogName = params.get(PARAM_BLOGNAME);
096            if (weblogName == null) {
097                weblogName = context.getPage().getName();
098            }
099            WikiEngine engine = context.getEngine();
100    
101            StringBuffer sb = new StringBuffer();
102    
103            String entryText = params.get(PARAM_ENTRYTEXT);
104            if (entryText == null) {
105                entryText = rb.getString("weblogentryplugin.newentry");
106            }
107    
108            String url = context.getURL(WikiContext.NONE, "NewBlogEntry.jsp", "page=" + engine.encodeName(weblogName));
109    
110            sb.append("<a href=\"" + url + "\">" + entryText + "</a>");
111    
112            return sb.toString();
113        }
114    
115        private int findFreeEntry(PageManager mgr,
116                                  String baseName,
117                                  String date)
118                throws ProviderException {
119            Collection everyone = mgr.getAllPages();
120            int max = 0;
121    
122            String startString = WeblogPlugin.makeEntryPage(baseName, date, "");
123    
124            for (Iterator i = everyone.iterator(); i.hasNext(); ) {
125                WikiPage p = (WikiPage) i.next();
126    
127                if (p.getName().startsWith(startString)) {
128                    try {
129                        String probableId = p.getName().substring(startString.length());
130    
131                        int id = Integer.parseInt(probableId);
132    
133                        if (id > max) {
134                            max = id;
135                        }
136                    } catch (NumberFormatException e) {
137                        log.debug("Was not a log entry: " + p.getName());
138                    }
139                }
140            }
141    
142            //
143            //  Find the first page that has no page lock.
144            //
145            int idx = max + 1;
146    
147            while (idx < MAX_BLOG_ENTRIES) {
148                WikiPage page = new WikiPage(mgr.getEngine(),
149                        WeblogPlugin.makeEntryPage(baseName,
150                                date,
151                                Integer.toString(idx)));
152                PageLock lock = mgr.getCurrentLock(page);
153    
154                if (lock == null) {
155                    break;
156                }
157    
158                idx++;
159            }
160    
161            return idx;
162        }
163    
164    }