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*/ 019 020package org.apache.wiki.diff; 021 022import org.apache.logging.log4j.LogManager; 023import org.apache.logging.log4j.Logger; 024import org.apache.wiki.api.core.Context; 025import org.apache.wiki.api.core.Engine; 026import org.apache.wiki.api.exceptions.NoRequiredPropertyException; 027import org.apache.wiki.api.providers.PageProvider; 028import org.apache.wiki.pages.PageManager; 029import org.apache.wiki.util.ClassUtil; 030 031import java.io.IOException; 032import java.lang.reflect.InvocationTargetException; 033import java.util.Properties; 034 035 036/** 037 * Load, initialize and delegate to the DiffProvider that will actually do the work. 038 */ 039public class DefaultDifferenceManager implements DifferenceManager { 040 041 private static final Logger log = LogManager.getLogger( DefaultDifferenceManager.class ); 042 043 private DiffProvider m_provider; 044 045 /** 046 * Creates a new DifferenceManager for the given engine. 047 * 048 * @param engine The Engine. 049 * @param props A set of properties. 050 */ 051 public DefaultDifferenceManager( final Engine engine, final Properties props ) { 052 loadProvider( props ); 053 initializeProvider( engine, props ); 054 055 log.info( "Using difference provider: " + m_provider.getProviderInfo() ); 056 } 057 058 private void loadProvider( final Properties props ) { 059 final String providerClassName = props.getProperty( PROP_DIFF_PROVIDER, TraditionalDiffProvider.class.getName() ); 060 try { 061 final Class< ? > providerClass = ClassUtil.findClass("org.apache.wiki.diff", providerClassName ); 062 m_provider = (DiffProvider) providerClass.getDeclaredConstructor().newInstance(); 063 } catch( final ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e ) { 064 log.warn("Failed loading DiffProvider, will use NullDiffProvider.", e); 065 } 066 067 if( m_provider == null ) { 068 m_provider = new DiffProvider.NullDiffProvider(); 069 } 070 } 071 072 073 private void initializeProvider( final Engine engine, final Properties props ) { 074 try { 075 m_provider.initialize( engine, props ); 076 } catch( final NoRequiredPropertyException | IOException e ) { 077 log.warn( "Failed initializing DiffProvider, will use NullDiffProvider.", e ); 078 m_provider = new DiffProvider.NullDiffProvider(); //doesn't need init'd 079 } 080 } 081 082 /** 083 * Returns valid XHTML string to be used in any way you please. 084 * 085 * @param context The Wiki Context 086 * @param firstWikiText The old text 087 * @param secondWikiText the new text 088 * @return XHTML, or empty string, if no difference detected. 089 */ 090 @Override 091 public String makeDiff( final Context context, final String firstWikiText, final String secondWikiText ) { 092 String diff; 093 try { 094 diff = m_provider.makeDiffHtml( context, firstWikiText, secondWikiText ); 095 096 if( diff == null ) { 097 diff = ""; 098 } 099 } catch( final Exception e ) { 100 diff = "Failed to create a diff, check the logs."; 101 log.warn( diff, e ); 102 } 103 return diff; 104 } 105 106 /** 107 * Returns a diff of two versions of a page. 108 * <p> 109 * Note that the API was changed in 2.6 to provide a WikiContext object! 110 * 111 * @param context The WikiContext of the page you wish to get a diff from 112 * @param version1 Version number of the old page. If WikiPageProvider.LATEST_VERSION (-1), then uses current page. 113 * @param version2 Version number of the new page. If WikiPageProvider.LATEST_VERSION (-1), then uses current page. 114 * 115 * @return A HTML-ized difference between two pages. If there is no difference, returns an empty string. 116 */ 117 @Override 118 public String getDiff( final Context context, final int version1, final int version2 ) { 119 final String page = context.getPage().getName(); 120 String page1 = context.getEngine().getManager( PageManager.class ).getPureText( page, version1 ); 121 final String page2 = context.getEngine().getManager( PageManager.class ).getPureText( page, version2 ); 122 123 // Kludge to make diffs for new pages to work this way. 124 if( version1 == PageProvider.LATEST_VERSION ) { 125 page1 = ""; 126 } 127 128 return makeDiff( context, page1, page2 ); 129 } 130 131} 132