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 */
019package org.apache.wiki.plugin;
020
021import java.text.SimpleDateFormat;
022import java.util.Collection;
023import java.util.Date;
024import java.util.Iterator;
025import java.util.Map;
026import java.util.ResourceBundle;
027
028import org.apache.log4j.Logger;
029import org.apache.wiki.PageLock;
030import org.apache.wiki.PageManager;
031import org.apache.wiki.WikiContext;
032import org.apache.wiki.WikiEngine;
033import org.apache.wiki.WikiPage;
034import org.apache.wiki.api.exceptions.PluginException;
035import org.apache.wiki.api.exceptions.ProviderException;
036import org.apache.wiki.api.plugin.WikiPlugin;
037import org.apache.wiki.preferences.Preferences;
038
039/**
040 * Builds a simple weblog.
041 * <p/>
042 * <p>Parameters : </p>
043 * <ul>
044 * <li><b>entrytext</b> - text of the link </li>
045 * <li><b>page</b> - if set, the entry is added to the named blog page. The default is the current page. </li>
046 * </ul>
047 *
048 * @since 1.9.21
049 */
050public class WeblogEntryPlugin implements WikiPlugin {
051    private static Logger log = Logger.getLogger(WeblogEntryPlugin.class);
052
053    private static final int MAX_BLOG_ENTRIES = 10000; // Just a precaution.
054
055    /**
056     * Parameter name for setting the entrytext  Value is <tt>{@value}</tt>.
057     */
058    public static final String PARAM_ENTRYTEXT = "entrytext";
059    /**
060     * Optional parameter: page that actually contains the blog.
061     * This lets us provide a "new entry" link for a blog page 
062     * somewhere else than on the page itself.
063     */
064    // "page" for uniform naming with WeblogPlugin...
065    /**
066     * Parameter name for setting the page Value is <tt>{@value}</tt>.
067     */
068    public static final String PARAM_BLOGNAME = "page";
069
070    /**
071     * Returns a new page name for entries.  It goes through the list of
072     * all blog pages, and finds out the next in line.
073     *
074     * @param engine   A WikiEngine
075     * @param blogName The page (or blog) name.
076     * @return A new name.
077     * @throws ProviderException If something goes wrong.
078     */
079    public String getNewEntryPage(WikiEngine engine, String blogName)
080            throws ProviderException {
081        SimpleDateFormat fmt = new SimpleDateFormat(WeblogPlugin.DEFAULT_DATEFORMAT);
082        String today = fmt.format(new Date());
083
084        int entryNum = findFreeEntry(engine.getPageManager(),
085                blogName,
086                today);
087
088
089        String blogPage = WeblogPlugin.makeEntryPage(blogName,
090                today,
091                "" + entryNum);
092
093        return blogPage;
094    }
095
096    /**
097     * {@inheritDoc}
098     */
099    public String execute(WikiContext context, Map<String, String> params)
100            throws PluginException {
101        ResourceBundle rb = Preferences.getBundle(context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
102
103        String weblogName = params.get(PARAM_BLOGNAME);
104        if (weblogName == null) {
105            weblogName = context.getPage().getName();
106        }
107        WikiEngine engine = context.getEngine();
108
109        StringBuilder sb = new StringBuilder();
110
111        String entryText = params.get(PARAM_ENTRYTEXT);
112        if (entryText == null) {
113            entryText = rb.getString("weblogentryplugin.newentry");
114        }
115
116        String url = context.getURL(WikiContext.NONE, "NewBlogEntry.jsp", "page=" + engine.encodeName(weblogName));
117
118        sb.append("<a href=\"" + url + "\">" + entryText + "</a>");
119
120        return sb.toString();
121    }
122
123    private int findFreeEntry(PageManager mgr,
124                              String baseName,
125                              String date)
126            throws ProviderException {
127        Collection everyone = mgr.getAllPages();
128        int max = 0;
129
130        String startString = WeblogPlugin.makeEntryPage(baseName, date, "");
131
132        for (Iterator i = everyone.iterator(); i.hasNext(); ) {
133            WikiPage p = (WikiPage) i.next();
134
135            if (p.getName().startsWith(startString)) {
136                try {
137                    String probableId = p.getName().substring(startString.length());
138
139                    int id = Integer.parseInt(probableId);
140
141                    if (id > max) {
142                        max = id;
143                    }
144                } catch (NumberFormatException e) {
145                    log.debug("Was not a log entry: " + p.getName());
146                }
147            }
148        }
149
150        //
151        //  Find the first page that has no page lock.
152        //
153        int idx = max + 1;
154
155        while (idx < MAX_BLOG_ENTRIES) {
156            WikiPage page = new WikiPage(mgr.getEngine(),
157                    WeblogPlugin.makeEntryPage(baseName,
158                            date,
159                            Integer.toString(idx)));
160            PageLock lock = mgr.getCurrentLock(page);
161
162            if (lock == null) {
163                break;
164            }
165
166            idx++;
167        }
168
169        return idx;
170    }
171
172}