org.apache.velocity.tools.generic.MarkupTool Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of velocity-tools-generic Show documentation
Show all versions of velocity-tools-generic Show documentation
Generic tools that can be used in any context.
PLEASE NOTE: this is a temporary fork to unblock projects migrating to Jakarta,
but I won't continue maintaining it in the future as the Velocity team doesn't
understand the value of Jakarta. I strongly suggest you plan a switch to a more
modern template engine such as Thymeleaf.
The newest version!
package org.apache.velocity.tools.generic;
/*
* 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.
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.velocity.tools.config.DefaultKey;
/**
* NOTE: This tools is considered "alpha" quality due to lack of testing
* and a generally unpolished API. Feel free to use but expect changes.
* Also, this is not automatically provided via the default tools.xml file.
*
*
*
* A tool to make it easy to generate XML or HTML on the fly. It uses a CSS-type
* syntax with a vaguely jQuery-ish API to help you generate the markup you need.
*
* Example uses in a template:
* #set( $foospan = $markup.span.id($foo.id).body($foo) )
* $markup.tag('table tr.bar td').body("This is $foospan")
*
* Output:
* <table>
* <tr class="bar">
* <td>This is <span id="foo1">my first foo.</span></td>
* </tr>
* </table>
*
*
* Example tools.xml config:
* <tools>
* <toolbox scope="application">
* <tool class="org.apache.velocity.tools.generic.alpha.MarkupTool"/>
* </toolbox>
* </tools>
*
*
* @author Nathan Bubna
* @since VelocityTools 2.0
* @version $Id$
*/
@DefaultKey("mark")
public class MarkupTool extends SafeConfig implements Serializable
{
private static final long serialVersionUID = -777597069616274442L;
public static final String DEFAULT_TAB = " ";
public static final String DEFAULT_DELIMITER = " ";
private String tab = DEFAULT_TAB;
private String delim = DEFAULT_DELIMITER;
/**
* Configuration
* @param tab tab string
*/
public void setTab(String tab)
{
if (isConfigLocked())
{
getLog().error("setTab() failure: configuration is locked");
}
else
{
this.tab = tab;
}
}
public String getTab()
{
return this.tab;
}
public Tag get(String tag)
{
return tag(tag);
}
public Tag tag(String definition)
{
String[] tags = split(definition);
Tag last = null;
for (int i=0; i < tags.length; i++)
{
Tag tag = parse(tags[i]);
if (last != null)
{
last.append(tag);
}
last = tag;
}
return last;
}
protected String[] split(String me)
{
//TODO: fix escaped delimiters
return me.split(delim);
}
private static enum Mode { NAME, ID, CLASS, ATTR }
protected Tag parse(String definition)
{
StringBuilder store = new StringBuilder();
Tag tag = new Tag(this);
Mode mode = Mode.NAME;
for (int i=0; i < definition.length(); i++)
{
char c = definition.charAt(i);
if (c == '#')
{
store = clear(mode, tag, store, true);
mode = Mode.ID;
}
else if (c == '.')
{
store = clear(mode, tag, store, true);
mode = Mode.CLASS;
}
else if (c == '[')
{
store = clear(mode, tag, store, true);
mode = Mode.ATTR;
}
else if (c == ']')
{
store = clear(mode, tag, store, true);
mode = Mode.NAME;
}
else
{
store.append(c);
}
}
clear(mode, tag, store, false);
return tag;
}
private StringBuilder clear(Mode mode, Tag tag, StringBuilder val, boolean emptyStore)
{
if (val.length() > 0)
{
String s = val.toString();
switch (mode)
{
case NAME:
tag.name(s);
break;
case ID:
tag.id(s);
break;
case CLASS:
tag.addClass(s);
break;
case ATTR:
if (s.indexOf('=') > 0)
{
String[] kv = s.split("=");
tag.attr(kv[0], kv[1]);
}
else
{
tag.attr(s, null);
}
break;
}
if (emptyStore)
{
return new StringBuilder();
}
return val;
}
else
{
// already is clean
return val;
}
}
public static class Tag
{
private MarkupTool tool;
private Tag parent;
private Object name;
private Object id;
private List