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