    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.markdown.extensions.jspwikilinks.postprocessor;
    020
    021import com.vladsch.flexmark.ast.Link;
    022import com.vladsch.flexmark.parser.PostProcessor;
    023import com.vladsch.flexmark.parser.block.NodePostProcessor;
    024import com.vladsch.flexmark.util.ast.Document;
    025import com.vladsch.flexmark.util.ast.Node;
    026import com.vladsch.flexmark.util.ast.NodeTracker;
    027import org.apache.commons.lang3.StringUtils;
    028import org.apache.oro.text.regex.Pattern;
    029import org.apache.wiki.api.core.Context;
    030import org.apache.wiki.markdown.nodes.JSPWikiLink;
    031import org.apache.wiki.parser.LinkParsingOperations;
    032import org.apache.wiki.parser.MarkupParser;
    033import org.apache.wiki.util.TextUtil;
    034
    035import java.util.List;
    036
    037
    038/**
    039 * {@link NodePostProcessor} to convert {@link Link}s into {@link JSPWikiLink}s.
    040 *
    041 * Acts as a factory of {@link NodePostProcessorState}, which are the classes generating the extra markup for each concrete type of link.
    042 */
    043public class JSPWikiLinkNodePostProcessor extends NodePostProcessor {
    044
    045    protected final Context m_context;
    046    protected final LinkParsingOperations linkOperations;
    047    private final boolean isImageInlining;
    048    private final List< Pattern > inlineImagePatterns;
    049    protected boolean m_useOutlinkImage = true;
    050    protected final Document document;
    051
    052    public JSPWikiLinkNodePostProcessor( final Context m_context,
    053                                         final Document document,
    054                                         final boolean isImageInlining,
    055                                         final List< Pattern > inlineImagePatterns ) {
    056        this.m_context = m_context;
    057        this.document = document;
    058        linkOperations = new LinkParsingOperations( m_context );
    059        this.isImageInlining = isImageInlining;
    060        this.inlineImagePatterns = inlineImagePatterns;
    061        m_useOutlinkImage = m_context.getBooleanWikiProperty( MarkupParser.PROP_USEOUTLINKIMAGE, m_useOutlinkImage );
    062    }
    063
    064    /**
    065     * {@inheritDoc}
    066     *
    067     * @see PostProcessor#process(NodeTracker, Node)
    068     */
    069    @Override
    070    public void process( final NodeTracker state, final Node node ) {
    071        if( node instanceof Link ) {
    072            final JSPWikiLink link = replaceLinkWithJSPWikiLink( state, node );
    073
    074            final NodePostProcessorState< JSPWikiLink > linkPostProcessor;
    075            if( linkOperations.isAccessRule( link.getUrl().toString() ) ) {
    076                linkPostProcessor = new AccessRuleLinkNodePostProcessorState( m_context );
    077            } else if( linkOperations.isMetadata( link.getUrl().toString() ) ) {
    078                linkPostProcessor = new MetadataLinkNodePostProcessorState( m_context );
    079            } else if( linkOperations.isPluginLink( link.getUrl().toString() ) ) {
    080                linkPostProcessor = new PluginLinkNodePostProcessorState( m_context );
    081            } else if( linkOperations.isVariableLink( link.getUrl().toString() ) ) {
    082                linkPostProcessor = new VariableLinkNodePostProcessorState( m_context );
    083            } else if( linkOperations.isExternalLink( link.getUrl().toString() ) ) {
    084                linkPostProcessor = new ExternalLinkNodePostProcessorState( m_context, isImageInlining, inlineImagePatterns );
    085            } else if( linkOperations.isInterWikiLink( link.getUrl().toString() ) ) {
    086                linkPostProcessor = new InterWikiLinkNodePostProcessorState( m_context, document, isImageInlining, inlineImagePatterns );
    087            } else if( StringUtils.startsWith( link.getUrl().toString(), "#" ) ) {
    088                linkPostProcessor = new LocalFootnoteLinkNodePostProcessorState( m_context );
    089            } else if( TextUtil.isNumber( link.getUrl().toString() ) ) {
    090                linkPostProcessor = new LocalFootnoteRefLinkNodePostProcessorState( m_context );
    091            } else {
    092                linkPostProcessor = new LocalLinkNodePostProcessorState( m_context, isImageInlining, inlineImagePatterns );
    093            }
    094            linkPostProcessor.process( state, link );
    095        }
    096    }
    097
    098    JSPWikiLink replaceLinkWithJSPWikiLink( final NodeTracker state, final Node node ) {
    099        final JSPWikiLink link = new JSPWikiLink( ( Link )node );
    100        final Node previous = node.getPrevious();
    101        final Node parent = node.getParent();
    102
    103        link.takeChildren( node );
    104        node.unlink();
    105
    106        if( previous != null ) {
    107            previous.insertAfter( link );
    108        } else if( parent != null ) {
    109            parent.appendChild( link );
    110        }
    111
    112        state.nodeRemoved( node );
    113        state.nodeAddedWithChildren( link );
    114        return link;
    115    }
    116
    117}