📄 velocitypanel.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.wicket.velocity.markup.html;import java.io.IOException;import java.io.Reader;import java.io.StringReader;import java.io.StringWriter;import java.util.Map;import org.apache.velocity.VelocityContext;import org.apache.velocity.app.Velocity;import org.apache.velocity.exception.MethodInvocationException;import org.apache.velocity.exception.ParseErrorException;import org.apache.velocity.exception.ResourceNotFoundException;import org.apache.wicket.WicketRuntimeException;import org.apache.wicket.markup.ComponentTag;import org.apache.wicket.markup.Markup;import org.apache.wicket.markup.MarkupParser;import org.apache.wicket.markup.MarkupResourceStream;import org.apache.wicket.markup.MarkupStream;import org.apache.wicket.markup.html.panel.Panel;import org.apache.wicket.model.IModel;import org.apache.wicket.util.resource.IStringResourceStream;import org.apache.wicket.util.resource.ResourceStreamNotFoundException;import org.apache.wicket.util.resource.StringResourceStream;import org.apache.wicket.util.string.Strings;/** * Panel that displays the result of rendering a <a * href="http://jakarta.apache.org/velocity">Velocity</a> template. The template itself can be any * <code><a href="http://wicket.apache.org/wicket/apidocs/org/apache/wicket/util/resource/IStringResourceStream.html">IStringResourceStream</a></code> * implementation, of which there are a number of convenient implementations in the wicket.util * package. The model can be any normal * <code><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Map.html">Map</a></code>, * which will be used to create the * <code><a href="http://jakarta.apache.org/velocity/docs/api/org/apache/velocity/VelocityContext.html">VelocityContext</a></code>. * * <p> * <b>Note:</b> Be sure to properly initialize the Velocity engine before using * <code>VelocityPanel</code>. * </p> */public abstract class VelocityPanel extends Panel{ /** * Convenience factory method to create a {@link VelocityPanel} instance with a given * {@link IStringResourceStream template resource}. * * @param id * Component id * @param model * optional model for variable substituation. * @param templateResource * The template resource * @return */ public static VelocityPanel forTemplateResource(String id, IModel model, final IStringResourceStream templateResource) { if (templateResource == null) { throw new IllegalArgumentException("argument templateResource must be not null"); } return new VelocityPanel(id, model) { protected IStringResourceStream getTemplateResource() { return templateResource; } }; } /** * Construct. * * @param id * Component id * @param templateResource * The velocity template as a string resource * @param model * Model with variables that can be substituted by Velocity. Must return a * {@link Map}. */ public VelocityPanel(final String id, final IModel/* <Map> */model) { super(id, model); } /** * Gets a reader for the velocity template. * * @return reader for the velocity template */ private Reader getTemplateReader() { final IStringResourceStream resource = getTemplateResource(); if (resource == null) { throw new IllegalArgumentException("getTemplateResource must return a resource"); } final String template = resource.asString(); if (template != null) { return new StringReader(template); } return null; } /** * Either print or rethrow the throwable. * * @param exception * the cause * @param markupStream * the markup stream * @param openTag * the open tag */ private void onException(final Exception exception, final MarkupStream markupStream, final ComponentTag openTag) { if (!throwVelocityExceptions()) { // print the exception on the panel String stackTraceAsString = Strings.toString(exception); replaceComponentTagBody(markupStream, openTag, stackTraceAsString); } else { // rethrow the exception throw new WicketRuntimeException(exception); } } /** * Gets whether to escape HTML characters. * * @return whether to escape HTML characters. The default value is false. */ protected boolean escapeHtml() { return false; } /** * Returns the template resource passed to the constructor. * * @return The template resource */ protected abstract IStringResourceStream getTemplateResource(); /** * @see org.apache.wicket.markup.html.panel.Panel#onComponentTagBody(org.apache.wicket.markup.MarkupStream, * org.apache.wicket.markup.ComponentTag) */ protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) { final Reader templateReader = getTemplateReader(); if (templateReader != null) { // Get model as a map final Map map = (Map)getModelObject(); // create a Velocity context object using the model if set final VelocityContext ctx = new VelocityContext(map); // create a writer for capturing the Velocity output StringWriter writer = new StringWriter(); // string to be used as the template name for log messages in case // of error final String logTag = getId(); try { // execute the velocity script and capture the output in writer Velocity.evaluate(ctx, writer, logTag, templateReader); // replace the tag's body the Velocity output String result = writer.toString(); if (escapeHtml()) { // encode the result in order to get valid html output that // does not break the rest of the page result = Strings.escapeMarkup(result).toString(); } if (!parseGeneratedMarkup()) { // now replace the body of the tag with the velocity merge // result replaceComponentTagBody(markupStream, openTag, result); } else { // now parse the velocity merge result Markup markup; try { MarkupParser parser = getApplication().getMarkupSettings() .getMarkupParserFactory().newMarkupParser( new MarkupResourceStream(new StringResourceStream(result))); markup = parser.parse(); } catch (ResourceStreamNotFoundException e) { throw new RuntimeException("Could not parse resulting markup", e); } markupStream.skipRawMarkup(); renderAll(new MarkupStream(markup)); } } catch (ParseErrorException e) { onException(e, markupStream, openTag); } catch (MethodInvocationException e) { onException(e, markupStream, openTag); } catch (ResourceNotFoundException e) { onException(e, markupStream, openTag); } catch (IOException e) { onException(e, markupStream, openTag); } } else { replaceComponentTagBody(markupStream, openTag, ""); // just empty it } } /** * Gets whether to parse the resulting Wicket markup. * * @return whether to parse the resulting Wicket markup. The default is false. */ protected boolean parseGeneratedMarkup() { return false; } /** * Whether any velocity exception should be trapped and displayed on the panel (false) or thrown * up to be handled by the exception mechanism of Wicket (true). The default is false, which * traps and displays any exception without having consequences for the other components on the * page. * <p> * Trapping these exceptions without disturbing the other components is especially usefull in * CMS like applications, where 'normal' users are allowed to do basic scripting. On errors, you * want them to be able to have them correct them while the rest of the application keeps on * working. * </p> * * @return Whether any velocity exceptions should be thrown or trapped. The default is false. */ protected boolean throwVelocityExceptions() { return false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -