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