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.util.ast.Document;
022import com.vladsch.flexmark.util.ast.Node;
023import com.vladsch.flexmark.util.ast.NodeTracker;
024import com.vladsch.flexmark.util.sequence.CharSubSequence;
025import org.apache.log4j.Logger;
026import org.apache.oro.text.regex.Pattern;
027import org.apache.wiki.api.core.Context;
028import org.apache.wiki.i18n.InternationalizationManager;
029import org.apache.wiki.markdown.nodes.JSPWikiLink;
030import org.apache.wiki.parser.LinkParsingOperations;
031import org.apache.wiki.parser.MarkupParser;
032import org.apache.wiki.preferences.Preferences;
033import org.apache.wiki.util.TextUtil;
034
035import java.text.MessageFormat;
036import java.util.List;
037import java.util.ResourceBundle;
038
039
040/**
041 * {@link NodePostProcessorState} which further post processes interwiki links.
042 */
043public class InterWikiLinkNodePostProcessorState implements NodePostProcessorState< JSPWikiLink > {
044
045    private static final Logger LOG = Logger.getLogger( InterWikiLinkNodePostProcessorState.class );
046    private final Context wikiContext;
047    private final LinkParsingOperations linkOperations;
048    private final boolean isImageInlining;
049    private final List< Pattern > inlineImagePatterns;
050    private final Document document;
051    private final boolean m_wysiwygEditorMode;
052    private boolean m_useOutlinkImage = true;
053
054    public InterWikiLinkNodePostProcessorState( final Context wikiContext,
055                                                final Document document,
056                                                final boolean isImageInlining,
057                                                final List< Pattern > inlineImagePatterns ) {
058        this.wikiContext = wikiContext;
059        this.linkOperations = new LinkParsingOperations( wikiContext );
060        this.isImageInlining = isImageInlining;
061        this.inlineImagePatterns = inlineImagePatterns;
062        this.document = document;
063        this.m_useOutlinkImage = wikiContext.getBooleanWikiProperty( MarkupParser.PROP_USEOUTLINKIMAGE, m_useOutlinkImage );
064        final Boolean wysiwygVariable = wikiContext.getVariable( Context.VAR_WYSIWYG_EDITOR_MODE );
065        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable : false;
066    }
067
068    /**
069     * {@inheritDoc}
070     *
071     * @see NodePostProcessorState#process(NodeTracker, Node)
072     */
073    @Override
074    public void process( final NodeTracker state, final JSPWikiLink link ) {
075        final String[] refAndPage = link.getUrl().toString().split( ":" );
076        if( !m_wysiwygEditorMode ) {
077            String urlReference = wikiContext.getEngine().getInterWikiURL( refAndPage[ 0 ] );
078            if( urlReference != null ) {
079                urlReference = TextUtil.replaceString( urlReference, "%s", refAndPage[ 1 ] );
080                if( linkOperations.isImageLink( urlReference, isImageInlining, inlineImagePatterns ) ) {
081                    new ImageLinkNodePostProcessorState( wikiContext, urlReference, link.hasRef() ).process( state, link );
082                } else {
083                    link.setUrl( CharSubSequence.of( urlReference ) );
084                }
085                if( linkOperations.isExternalLink( urlReference ) ) {
086                    NodePostProcessorStateCommonOperations.addOutlinkImage( state, link, wikiContext, m_useOutlinkImage );
087                }
088            } else {
089                LOG.debug( refAndPage[0] + " not recognized as InterWiki link [document node: " + document + "]" );
090                final Object[] args = { refAndPage[ 0 ] };
091                final ResourceBundle rb = Preferences.getBundle( wikiContext, InternationalizationManager.CORE_BUNDLE );
092                final String errMsg = MessageFormat.format( rb.getString( "markupparser.error.nointerwikiref" ), args );
093                NodePostProcessorStateCommonOperations.makeError( state, link, errMsg );
094            }
095        } else {
096            link.setUrl( CharSubSequence.of( refAndPage[0] + ":" + refAndPage[1] ) );
097        }
098    }
099
100}