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