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}