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 package org.apache.wiki.plugin;
020
021 import java.util.ArrayList;
022 import java.util.List;
023 import java.util.Map;
024
025 import org.apache.wiki.WikiContext;
026 import org.apache.wiki.WikiEngine;
027 import org.apache.wiki.WikiPage;
028 import org.apache.wiki.api.exceptions.PluginException;
029 import org.apache.wiki.api.exceptions.ProviderException;
030 import org.apache.wiki.api.plugin.WikiPlugin;
031 import org.apache.wiki.auth.AuthorizationManager;
032 import org.apache.wiki.auth.permissions.PermissionFactory;
033 import 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 */
050 public 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 StringBuffer res = new StringBuffer();
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)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 }