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.plugin; 020 021import java.util.ArrayList; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.wiki.WikiContext; 026import org.apache.wiki.WikiEngine; 027import org.apache.wiki.WikiPage; 028import org.apache.wiki.api.exceptions.PluginException; 029import org.apache.wiki.api.exceptions.ProviderException; 030import org.apache.wiki.api.plugin.WikiPlugin; 031import org.apache.wiki.auth.AuthorizationManager; 032import org.apache.wiki.auth.permissions.PermissionFactory; 033import org.apache.wiki.util.TextUtil; 034 035/** 036 * Inserts page contents. Muchos thanks to Scott Hurlbert for the initial code. 037 * 038 * <p>Parameters : </p> 039 * <ul> 040 * <li><b>page</b> - the name of the page to be inserted</li> 041 * <li><b>style</b> - the style to use</li> 042 * <li><b>maxlength</b> - the maximum length of the page to be inserted (page contents)</li> 043 * <li><b>class</b> - the class to use</li> 044 * <li><b>section</b> - the section of the page that has to be inserted (separated by "----"</li> 045 * <li><b>default</b> - the text to insert if the requested page does not exist</li> 046 * </ul> 047 * 048 * @since 2.1.37 049 */ 050public class InsertPage 051 implements WikiPlugin 052{ 053 /** Parameter name for setting the page. Value is <tt>{@value}</tt>. */ 054 public static final String PARAM_PAGENAME = "page"; 055 /** Parameter name for setting the style. Value is <tt>{@value}</tt>. */ 056 public static final String PARAM_STYLE = "style"; 057 /** Parameter name for setting the maxlength. Value is <tt>{@value}</tt>. */ 058 public static final String PARAM_MAXLENGTH = "maxlength"; 059 /** Parameter name for setting the class. Value is <tt>{@value}</tt>. */ 060 public static final String PARAM_CLASS = "class"; 061 /** Parameter name for setting the section. Value is <tt>{@value}</tt>. */ 062 public static final String PARAM_SECTION = "section"; 063 /** Parameter name for setting the default. Value is <tt>{@value}</tt>. */ 064 public static final String PARAM_DEFAULT = "default"; 065 066 private static final String DEFAULT_STYLE = ""; 067 068 /** This attribute is stashed in the WikiContext to make sure that we don't 069 * have circular references. 070 */ 071 public static final String ATTR_RECURSE = "org.apache.wiki.plugin.InsertPage.recurseCheck"; 072 073 /** 074 * {@inheritDoc} 075 */ 076 @SuppressWarnings("unchecked") 077 public String execute( WikiContext context, Map<String, String> params ) 078 throws PluginException 079 { 080 WikiEngine engine = context.getEngine(); 081 082 StringBuilder res = new StringBuilder(); 083 084 String clazz = params.get( PARAM_CLASS ); 085 String includedPage = params.get( PARAM_PAGENAME ); 086 String style = params.get( PARAM_STYLE ); 087 String defaultstr = params.get( PARAM_DEFAULT ); 088 int section = TextUtil.parseIntParameter(params.get( PARAM_SECTION ), -1 ); 089 int maxlen = TextUtil.parseIntParameter(params.get( PARAM_MAXLENGTH ), -1 ); 090 091 if( style == null ) style = DEFAULT_STYLE; 092 093 if( maxlen == -1 ) maxlen = Integer.MAX_VALUE; 094 095 if( includedPage != null ) 096 { 097 WikiPage page = null; 098 try 099 { 100 String pageName = engine.getFinalPageName( includedPage ); 101 if( pageName != null ) 102 { 103 page = engine.getPage( pageName ); 104 } 105 else 106 { 107 page = engine.getPage( includedPage ); 108 } 109 } 110 catch( ProviderException e ) 111 { 112 res.append( "<span class=\"error\">Page could not be found by the page provider.</span>" ); 113 return res.toString(); 114 } 115 116 if( page != null ) 117 { 118 // 119 // Check for recursivity 120 // 121 122 List<String> previousIncludes = (List<String>)context.getVariable( ATTR_RECURSE ); 123 124 if( previousIncludes != null ) 125 { 126 if( previousIncludes.contains( page.getName() ) ) 127 { 128 return "<span class=\"error\">Error: Circular reference - you can't include a page in itself!</span>"; 129 } 130 } 131 else 132 { 133 previousIncludes = new ArrayList<String>(); 134 } 135 136 previousIncludes.add( page.getName() ); 137 context.setVariable( ATTR_RECURSE, previousIncludes ); 138 139 // 140 // Check for permissions 141 // 142 AuthorizationManager mgr = engine.getAuthorizationManager(); 143 144 if( !mgr.checkPermission( context.getWikiSession(), 145 PermissionFactory.getPagePermission( page, "view") ) ) 146 { 147 res.append("<span class=\"error\">You do not have permission to view this included page.</span>"); 148 return res.toString(); 149 } 150 151 /** 152 * We want inclusion to occur within the context of 153 * its own page, because we need the links to be correct. 154 */ 155 156 WikiContext includedContext = (WikiContext) context.clone(); 157 includedContext.setPage( page ); 158 159 String pageData = engine.getPureText( page ); 160 String moreLink = ""; 161 162 if( section != -1 ) 163 { 164 try 165 { 166 pageData = TextUtil.getSection( pageData, section ); 167 } 168 catch( IllegalArgumentException e ) 169 { 170 throw new PluginException( e.getMessage() ); 171 } 172 } 173 174 if( pageData.length() > maxlen ) 175 { 176 pageData = pageData.substring( 0, maxlen )+" ..."; 177 moreLink = "<p><a href=\""+context.getURL(WikiContext.VIEW,includedPage)+"\">More...</a></p>"; 178 } 179 180 res.append("<div style=\""+style+"\""+(clazz != null ? " class=\""+clazz+"\"" : "")+">"); 181 res.append( engine.textToHTML( includedContext, pageData ) ); 182 res.append( moreLink ); 183 res.append("</div>"); 184 185 // 186 // Remove the name from the stack; we're now done with this. 187 // 188 previousIncludes.remove( page.getName() ); 189 context.setVariable( ATTR_RECURSE, previousIncludes ); 190 } 191 else 192 { 193 if( defaultstr != null ) 194 { 195 res.append( defaultstr ); 196 } 197 else 198 { 199 res.append("There is no page called '"+includedPage+"'. Would you like to "); 200 res.append("<a href=\""+context.getURL( WikiContext.EDIT, includedPage )+"\">create it?</a>"); 201 } 202 } 203 } 204 else 205 { 206 res.append("<span class=\"error\">"); 207 res.append("You have to define a page!"); 208 res.append("</span>"); 209 } 210 211 return res.toString(); 212 } 213 214}