YARN-9279. Remove the old hamlet package. (#2986)
Signed-off-by: Takanobu Asanuma <tasanuma@apache.org>
This commit is contained in:
parent
0d59500e8c
commit
c8073811b2
|
@ -378,34 +378,4 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<!-- TODO: Remove this profile when hamlet was removed. -->
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>java9</id>
|
||||
<activation>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>org/apache/hadoop/yarn/webapp/hamlet/**</exclude>
|
||||
</excludes>
|
||||
<testExcludes>
|
||||
<exclude>org/apache/hadoop/yarn/webapp/hamlet/**</exclude>
|
||||
</testExcludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludePackageNames>org.apache.hadoop.yarn.webapp.hamlet</excludePackageNames>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,451 +0,0 @@
|
|||
/**
|
||||
* 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.hadoop.yarn.webapp.hamlet;
|
||||
|
||||
import org.apache.hadoop.thirdparty.com.google.common.collect.Sets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.util.StringUtils;
|
||||
import org.apache.hadoop.yarn.webapp.WebAppException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Generates a specific hamlet implementation class from a spec class
|
||||
* using a generic hamlet implementation class.
|
||||
* @deprecated Use org.apache.hadoop.yarn.webapp.hamlet2 package instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@InterfaceAudience.LimitedPrivate({"YARN", "MapReduce"})
|
||||
public class HamletGen {
|
||||
static final Logger LOG = LoggerFactory.getLogger(HamletGen.class);
|
||||
static final Options opts = new Options();
|
||||
static {
|
||||
opts.addOption("h", "help", false, "Print this help message").
|
||||
addOption("s", "spec-class", true,
|
||||
"The class that holds the spec interfaces. e.g. HamletSpec").
|
||||
addOption("i", "impl-class", true,
|
||||
"An implementation class. e.g. HamletImpl").
|
||||
addOption("o", "output-class", true, "Output class name").
|
||||
addOption("p", "output-package", true, "Output package name");
|
||||
};
|
||||
|
||||
static final Pattern elementRegex = Pattern.compile("^[A-Z][A-Z0-9]*$");
|
||||
|
||||
int bytes = 0;
|
||||
PrintWriter out;
|
||||
final Set<String> endTagOptional = Sets.newHashSet();
|
||||
final Set<String> inlineElements = Sets.newHashSet();
|
||||
Class<?> top; // html top-level interface
|
||||
String hamlet; // output class simple name;
|
||||
boolean topMode;
|
||||
|
||||
/**
|
||||
* Generate a specific Hamlet implementation from a spec.
|
||||
* @param specClass holds hamlet interfaces. e.g. {@link HamletSpec}
|
||||
* @param implClass a generic hamlet implementation. e.g. {@link HamletImpl}
|
||||
* @param outputName name of the output class. e.g. {@link Hamlet}
|
||||
* @param outputPkg package name of the output class.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void generate(Class<?> specClass, Class<?> implClass,
|
||||
String outputName, String outputPkg) throws IOException {
|
||||
LOG.info("Generating {} using {} and {}", new Object[]{outputName,
|
||||
specClass, implClass});
|
||||
out = new PrintWriter(outputName +".java", "UTF-8");
|
||||
hamlet = basename(outputName);
|
||||
String pkg = pkgName(outputPkg, implClass.getPackage().getName());
|
||||
puts(0, "// Generated by HamletGen. Do NOT edit!\n",
|
||||
"package ", pkg, ";\n",
|
||||
"import java.io.PrintWriter;\n",
|
||||
"import java.util.EnumSet;\n",
|
||||
"import static java.util.EnumSet.*;\n",
|
||||
"import static ", implClass.getName(), ".EOpt.*;\n",
|
||||
"import org.apache.hadoop.yarn.webapp.SubView;");
|
||||
String implClassName = implClass.getSimpleName();
|
||||
if (!implClass.getPackage().getName().equals(pkg)) {
|
||||
puts(0, "import ", implClass.getName(), ';');
|
||||
}
|
||||
puts(0, "\n",
|
||||
"public class ", hamlet, " extends ", implClassName,
|
||||
" implements ", specClass.getSimpleName(), "._Html {\n",
|
||||
" public ", hamlet, "(PrintWriter out, int nestLevel,",
|
||||
" boolean wasInline) {\n",
|
||||
" super(out, nestLevel, wasInline);\n",
|
||||
" }\n\n", // inline is context sensitive
|
||||
" static EnumSet<EOpt> opt(boolean endTag, boolean inline, ",
|
||||
"boolean pre) {\n",
|
||||
" EnumSet<EOpt> opts = of(ENDTAG);\n",
|
||||
" if (!endTag) opts.remove(ENDTAG);\n",
|
||||
" if (inline) opts.add(INLINE);\n",
|
||||
" if (pre) opts.add(PRE);\n",
|
||||
" return opts;\n",
|
||||
" }");
|
||||
initLut(specClass);
|
||||
genImpl(specClass, implClassName, 1);
|
||||
LOG.info("Generating {} methods", hamlet);
|
||||
genMethods(hamlet, top, 1);
|
||||
puts(0, "}");
|
||||
out.close();
|
||||
LOG.info("Wrote {} bytes to {}.java", bytes, outputName);
|
||||
}
|
||||
|
||||
String basename(String path) {
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
String pkgName(String pkg, String defaultPkg) {
|
||||
if (pkg == null || pkg.isEmpty()) return defaultPkg;
|
||||
return pkg;
|
||||
}
|
||||
|
||||
void initLut(Class<?> spec) {
|
||||
endTagOptional.clear();
|
||||
inlineElements.clear();
|
||||
for (Class<?> cls : spec.getClasses()) {
|
||||
Annotation a = cls.getAnnotation(HamletSpec.Element.class);
|
||||
if (a != null && !((HamletSpec.Element) a).endTag()) {
|
||||
endTagOptional.add(cls.getSimpleName());
|
||||
}
|
||||
if (cls.getSimpleName().equals("Inline")) {
|
||||
for (Method method : cls.getMethods()) {
|
||||
String retName = method.getReturnType().getSimpleName();
|
||||
if (isElement(retName)) {
|
||||
inlineElements.add(retName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void genImpl(Class<?> spec, String implClassName, int indent) {
|
||||
String specName = spec.getSimpleName();
|
||||
for (Class<?> cls : spec.getClasses()) {
|
||||
String className = cls.getSimpleName();
|
||||
if (cls.isInterface()) {
|
||||
genFactoryMethods(cls, indent);
|
||||
}
|
||||
if (isElement(className)) {
|
||||
LOG.info("Generating class {}<T>", className);
|
||||
puts(indent, "\n",
|
||||
"public class ", className, "<T extends _>",
|
||||
" extends EImp<T> implements ", specName, ".", className, " {\n",
|
||||
" public ", className, "(String name, T parent,",
|
||||
" EnumSet<EOpt> opts) {\n",
|
||||
" super(name, parent, opts);\n",
|
||||
" }");
|
||||
genMethods(className, cls, indent + 1);
|
||||
puts(indent, "}");
|
||||
} else if (className.equals("_Html")) {
|
||||
top = cls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void genFactoryMethods(Class<?> cls, int indent) {
|
||||
for (Method method : cls.getDeclaredMethods()) {
|
||||
String retName = method.getReturnType().getSimpleName();
|
||||
String methodName = method.getName();
|
||||
if (methodName.charAt(0) == '$') continue;
|
||||
if (isElement(retName) && method.getParameterTypes().length == 0) {
|
||||
genFactoryMethod(retName, methodName, indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void genMethods(String className, Class<?> cls, int indent) {
|
||||
topMode = (top != null && cls.equals(top));
|
||||
for (Method method : cls.getMethods()) {
|
||||
String retName = method.getReturnType().getSimpleName();
|
||||
if (method.getName().charAt(0) == '$') {
|
||||
genAttributeMethod(className, method, indent);
|
||||
} else if (isElement(retName)) {
|
||||
genNewElementMethod(className, method, indent);
|
||||
} else {
|
||||
genCurElementMethod(className, method, indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void genAttributeMethod(String className, Method method, int indent) {
|
||||
String methodName = method.getName();
|
||||
String attrName = methodName.substring(1).replace('_', '-');
|
||||
Type[] params = method.getGenericParameterTypes();
|
||||
echo(indent, "\n",
|
||||
"@Override\n",
|
||||
"public ", className, topMode ? " " : "<T> ", methodName, "(");
|
||||
if (params.length == 0) {
|
||||
puts(0, ") {");
|
||||
puts(indent,
|
||||
" addAttr(\"", attrName, "\", null);\n",
|
||||
" return this;\n", "}");
|
||||
} else if (params.length == 1) {
|
||||
String typeName = getTypeName(params[0]);
|
||||
puts(0, typeName, " value) {");
|
||||
if (typeName.equals("EnumSet<LinkType>")) {
|
||||
puts(indent,
|
||||
" addRelAttr(\"", attrName, "\", value);\n",
|
||||
" return this;\n", "}");
|
||||
} else if (typeName.equals("EnumSet<Media>")) {
|
||||
puts(indent,
|
||||
" addMediaAttr(\"", attrName, "\", value);\n",
|
||||
" return this;\n", "}");
|
||||
} else {
|
||||
puts(indent,
|
||||
" addAttr(\"", attrName, "\", value);\n",
|
||||
" return this;\n", "}");
|
||||
}
|
||||
} else {
|
||||
throwUnhandled(className, method);
|
||||
}
|
||||
}
|
||||
|
||||
String getTypeName(Type type) {
|
||||
if (type instanceof Class<?>) {
|
||||
return ((Class<?>)type).getSimpleName();
|
||||
}
|
||||
ParameterizedType pt = (ParameterizedType) type;
|
||||
return ((Class<?>)pt.getRawType()).getSimpleName() +"<"+
|
||||
((Class<?>)pt.getActualTypeArguments()[0]).getSimpleName() +">";
|
||||
}
|
||||
|
||||
void genFactoryMethod(String retName, String methodName, int indent) {
|
||||
puts(indent, "\n",
|
||||
"private <T extends _> ", retName, "<T> ", methodName,
|
||||
"_(T e, boolean inline) {\n",
|
||||
" return new ", retName, "<T>(\"", StringUtils.toLowerCase(retName),
|
||||
"\", e, opt(", !endTagOptional.contains(retName), ", inline, ",
|
||||
retName.equals("PRE"), ")); }");
|
||||
}
|
||||
|
||||
void genNewElementMethod(String className, Method method, int indent) {
|
||||
String methodName = method.getName();
|
||||
String retName = method.getReturnType().getSimpleName();
|
||||
Class<?>[] params = method.getParameterTypes();
|
||||
echo(indent, "\n",
|
||||
"@Override\n",
|
||||
"public ", retName, "<", className, topMode ? "> " : "<T>> ",
|
||||
methodName, "(");
|
||||
if (params.length == 0) {
|
||||
puts(0, ") {");
|
||||
puts(indent,
|
||||
topMode ? "" : " closeAttrs();\n",
|
||||
" return ", StringUtils.toLowerCase(retName), "_" + "(this, ",
|
||||
isInline(className, retName), ");\n", "}");
|
||||
} else if (params.length == 1) {
|
||||
puts(0, "String selector) {");
|
||||
puts(indent,
|
||||
" return setSelector(", methodName, "(), selector);\n", "}");
|
||||
} else {
|
||||
throwUnhandled(className, method);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isInline(String container, String className) {
|
||||
if ((container.equals("BODY") || container.equals(hamlet) ||
|
||||
container.equals("HEAD") || container.equals("HTML")) &&
|
||||
(className.equals("INS") || className.equals("DEL") ||
|
||||
className.equals("SCRIPT"))) {
|
||||
return false;
|
||||
}
|
||||
return inlineElements.contains(className);
|
||||
}
|
||||
|
||||
void genCurElementMethod(String className, Method method, int indent) {
|
||||
String methodName = method.getName();
|
||||
Class<?>[] params = method.getParameterTypes();
|
||||
if (topMode || params.length > 0) {
|
||||
echo(indent, "\n",
|
||||
"@Override\n",
|
||||
"public ", className, topMode ? " " : "<T> ", methodName, "(");
|
||||
}
|
||||
if (params.length == 0) {
|
||||
if (topMode) {
|
||||
puts(0, ") {");
|
||||
puts(indent, " return this;\n", "}");
|
||||
}
|
||||
} else if (params.length == 1) {
|
||||
if (methodName.equals("base")) {
|
||||
puts(0, "String href) {");
|
||||
puts(indent,
|
||||
" return base().$href(href)._();\n", "}");
|
||||
} else if (methodName.equals("script")) {
|
||||
puts(0, "String src) {");
|
||||
puts(indent,
|
||||
" return setScriptSrc(script(), src)._();\n", "}");
|
||||
} else if (methodName.equals("style")) {
|
||||
puts(0, "Object... lines) {");
|
||||
puts(indent,
|
||||
" return style().$type(\"text/css\")._(lines)._();\n", "}");
|
||||
} else if (methodName.equals("img")) {
|
||||
puts(0, "String src) {");
|
||||
puts(indent,
|
||||
" return ", methodName, "().$src(src)._();\n", "}");
|
||||
} else if (methodName.equals("br") || methodName.equals("hr") ||
|
||||
methodName.equals("col")) {
|
||||
puts(0, "String selector) {");
|
||||
puts(indent,
|
||||
" return setSelector(", methodName, "(), selector)._();\n", "}");
|
||||
} else if (methodName.equals("link")) {
|
||||
puts(0, "String href) {");
|
||||
puts(indent,
|
||||
" return setLinkHref(", methodName, "(), href)._();\n", "}");
|
||||
} else if (methodName.equals("_")) {
|
||||
if (params[0].getSimpleName().equals("Class")) {
|
||||
puts(0, "Class<? extends SubView> cls) {");
|
||||
puts(indent,
|
||||
" ", topMode ? "subView" : "_v", "(cls);\n",
|
||||
" return this;\n", "}");
|
||||
} else {
|
||||
puts(0, "Object... lines) {");
|
||||
puts(indent,
|
||||
" _p(", needsEscaping(className), ", lines);\n",
|
||||
" return this;\n", "}");
|
||||
}
|
||||
} else if (methodName.equals("_r")) {
|
||||
puts(0, "Object... lines) {");
|
||||
puts(indent,
|
||||
" _p(false, lines);\n",
|
||||
" return this;\n", "}");
|
||||
} else {
|
||||
puts(0, "String cdata) {");
|
||||
puts(indent,
|
||||
" return ", methodName, "()._(cdata)._();\n", "}");
|
||||
}
|
||||
} else if (params.length == 2) {
|
||||
if (methodName.equals("meta")) {
|
||||
puts(0, "String name, String content) {");
|
||||
puts(indent,
|
||||
" return meta().$name(name).$content(content)._();\n", "}");
|
||||
} else if (methodName.equals("meta_http")) {
|
||||
puts(0, "String header, String content) {");
|
||||
puts(indent,
|
||||
" return meta().$http_equiv(header).$content(content)._();\n",
|
||||
"}");
|
||||
} else if (methodName.equals("a")) {
|
||||
puts(0, "String href, String anchorText) {");
|
||||
puts(indent,
|
||||
" return a().$href(href)._(anchorText)._();\n", "}");
|
||||
} else if (methodName.equals("bdo")) {
|
||||
puts(0, "Dir dir, String cdata) {");
|
||||
puts(indent, " return bdo().$dir(dir)._(cdata)._();\n", "}");
|
||||
} else if (methodName.equals("label")) {
|
||||
puts(0, "String forId, String cdata) {");
|
||||
puts(indent, " return label().$for(forId)._(cdata)._();\n", "}");
|
||||
} else if (methodName.equals("param")) {
|
||||
puts(0, "String name, String value) {");
|
||||
puts(indent,
|
||||
" return param().$name(name).$value(value)._();\n", "}");
|
||||
} else {
|
||||
puts(0, "String selector, String cdata) {");
|
||||
puts(indent,
|
||||
" return setSelector(", methodName,
|
||||
"(), selector)._(cdata)._();\n", "}");
|
||||
}
|
||||
} else if (params.length == 3) {
|
||||
if (methodName.equals("a")) {
|
||||
puts(0, "String selector, String href, String anchorText) {");
|
||||
puts(indent,
|
||||
" return setSelector(a(), selector)",
|
||||
".$href(href)._(anchorText)._();\n", "}");
|
||||
}
|
||||
} else {
|
||||
throwUnhandled(className, method);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean needsEscaping(String eleName) {
|
||||
return !eleName.equals("SCRIPT") && !eleName.equals("STYLE");
|
||||
}
|
||||
|
||||
static void throwUnhandled(String className, Method method) {
|
||||
throw new WebAppException("Unhandled " + className + "#" + method);
|
||||
}
|
||||
|
||||
void echo(int indent, Object... args) {
|
||||
String prev = null;
|
||||
for (Object o : args) {
|
||||
String s = String.valueOf(o);
|
||||
if (!s.isEmpty() && !s.equals("\n") &&
|
||||
(prev == null || prev.endsWith("\n"))) {
|
||||
indent(indent);
|
||||
}
|
||||
prev = s;
|
||||
out.print(s);
|
||||
bytes += s.length();
|
||||
}
|
||||
}
|
||||
|
||||
void indent(int indent) {
|
||||
for (int i = 0; i < indent; ++i) {
|
||||
out.print(" ");
|
||||
bytes += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void puts(int indent, Object... args) {
|
||||
echo(indent, args);
|
||||
out.println();
|
||||
++bytes;
|
||||
}
|
||||
|
||||
boolean isElement(String s) {
|
||||
return elementRegex.matcher(s).matches();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
CommandLine cmd = new GnuParser().parse(opts, args);
|
||||
if (cmd.hasOption("help")) {
|
||||
new HelpFormatter().printHelp("Usage: hbgen [OPTIONS]", opts);
|
||||
return;
|
||||
}
|
||||
// defaults
|
||||
Class<?> specClass = HamletSpec.class;
|
||||
Class<?> implClass = HamletImpl.class;
|
||||
String outputClass = "HamletTmp";
|
||||
String outputPackage = implClass.getPackage().getName();
|
||||
if (cmd.hasOption("spec-class")) {
|
||||
specClass = Class.forName(cmd.getOptionValue("spec-class"));
|
||||
}
|
||||
if (cmd.hasOption("impl-class")) {
|
||||
implClass = Class.forName(cmd.getOptionValue("impl-class"));
|
||||
}
|
||||
if (cmd.hasOption("output-class")) {
|
||||
outputClass = cmd.getOptionValue("output-class");
|
||||
}
|
||||
if (cmd.hasOption("output-package")) {
|
||||
outputPackage = cmd.getOptionValue("output-package");
|
||||
}
|
||||
new HamletGen().generate(specClass, implClass, outputClass, outputPackage);
|
||||
}
|
||||
}
|
|
@ -1,387 +0,0 @@
|
|||
/**
|
||||
* 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.hadoop.yarn.webapp.hamlet;
|
||||
|
||||
import org.apache.hadoop.thirdparty.com.google.common.base.Joiner;
|
||||
import static org.apache.hadoop.thirdparty.com.google.common.base.Preconditions.*;
|
||||
import org.apache.hadoop.thirdparty.com.google.common.base.Splitter;
|
||||
import org.apache.hadoop.thirdparty.com.google.common.collect.Iterables;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.EnumSet;
|
||||
import static java.util.EnumSet.*;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.apache.commons.text.StringEscapeUtils.*;
|
||||
import static org.apache.hadoop.yarn.webapp.hamlet.HamletImpl.EOpt.*;
|
||||
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.yarn.webapp.SubView;
|
||||
import org.apache.hadoop.yarn.webapp.WebAppException;
|
||||
|
||||
|
||||
/**
|
||||
* A simple unbuffered generic hamlet implementation.
|
||||
*
|
||||
* Zero copy but allocation on every element, which could be
|
||||
* optimized to use a thread-local element pool.
|
||||
*
|
||||
* Prints HTML as it builds. So the order is important.
|
||||
* @deprecated Use org.apache.hadoop.yarn.webapp.hamlet2 package instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@InterfaceAudience.Private
|
||||
public class HamletImpl extends HamletSpec {
|
||||
private static final String INDENT_CHARS = " ";
|
||||
private static final Splitter SS = Splitter.on('.').
|
||||
omitEmptyStrings().trimResults();
|
||||
private static final Joiner SJ = Joiner.on(' ');
|
||||
private static final Joiner CJ = Joiner.on(", ");
|
||||
static final int S_ID = 0;
|
||||
static final int S_CLASS = 1;
|
||||
|
||||
int nestLevel;
|
||||
int indents; // number of indent() called. mostly for testing.
|
||||
private final PrintWriter out;
|
||||
private final StringBuilder sb = new StringBuilder(); // not shared
|
||||
private boolean wasInline = false;
|
||||
|
||||
/**
|
||||
* Element options. (whether it needs end tag, is inline etc.)
|
||||
*/
|
||||
public enum EOpt {
|
||||
/** needs end(close) tag */
|
||||
ENDTAG,
|
||||
/** The content is inline */
|
||||
INLINE,
|
||||
/** The content is preformatted */
|
||||
PRE
|
||||
};
|
||||
|
||||
/**
|
||||
* The base class for elements
|
||||
* @param <T> type of the parent (containing) element for the element
|
||||
*/
|
||||
public class EImp<T extends _> implements _Child {
|
||||
private final String name;
|
||||
private final T parent; // short cut for parent element
|
||||
private final EnumSet<EOpt> opts; // element options
|
||||
|
||||
private boolean started = false;
|
||||
private boolean attrsClosed = false;
|
||||
|
||||
EImp(String name, T parent, EnumSet<EOpt> opts) {
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T _() {
|
||||
closeAttrs();
|
||||
--nestLevel;
|
||||
printEndTag(name, opts);
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void _p(boolean quote, Object... args) {
|
||||
closeAttrs();
|
||||
for (Object s : args) {
|
||||
if (!opts.contains(PRE)) {
|
||||
indent(opts);
|
||||
}
|
||||
out.print(quote ? escapeHtml4(String.valueOf(s))
|
||||
: String.valueOf(s));
|
||||
if (!opts.contains(INLINE) && !opts.contains(PRE)) {
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void _v(Class<? extends SubView> cls) {
|
||||
closeAttrs();
|
||||
subView(cls);
|
||||
}
|
||||
|
||||
protected void closeAttrs() {
|
||||
if (!attrsClosed) {
|
||||
startIfNeeded();
|
||||
++nestLevel;
|
||||
out.print('>');
|
||||
if (!opts.contains(INLINE) && !opts.contains(PRE)) {
|
||||
out.println();
|
||||
}
|
||||
attrsClosed = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void addAttr(String name, String value) {
|
||||
checkState(!attrsClosed, "attribute added after content");
|
||||
startIfNeeded();
|
||||
printAttr(name, value);
|
||||
}
|
||||
|
||||
protected void addAttr(String name, Object value) {
|
||||
addAttr(name, String.valueOf(value));
|
||||
}
|
||||
|
||||
protected void addMediaAttr(String name, EnumSet<Media> media) {
|
||||
// 6.13 comma-separated list
|
||||
addAttr(name, CJ.join(media));
|
||||
}
|
||||
|
||||
protected void addRelAttr(String name, EnumSet<LinkType> types) {
|
||||
// 6.12 space-separated list
|
||||
addAttr(name, SJ.join(types));
|
||||
}
|
||||
|
||||
private void startIfNeeded() {
|
||||
if (!started) {
|
||||
printStartTag(name, opts);
|
||||
started = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void _inline(boolean choice) {
|
||||
if (choice) {
|
||||
opts.add(INLINE);
|
||||
} else {
|
||||
opts.remove(INLINE);
|
||||
}
|
||||
}
|
||||
|
||||
protected void _endTag(boolean choice) {
|
||||
if (choice) {
|
||||
opts.add(ENDTAG);
|
||||
} else {
|
||||
opts.remove(ENDTAG);
|
||||
}
|
||||
}
|
||||
|
||||
protected void _pre(boolean choice) {
|
||||
if (choice) {
|
||||
opts.add(PRE);
|
||||
} else {
|
||||
opts.remove(PRE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Generic<T extends _> extends EImp<T> implements PCData {
|
||||
Generic(String name, T parent, EnumSet<EOpt> opts) {
|
||||
super(name, parent, opts);
|
||||
}
|
||||
|
||||
public Generic<T> _inline() {
|
||||
super._inline(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generic<T> _noEndTag() {
|
||||
super._endTag(false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generic<T> _pre() {
|
||||
super._pre(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generic<T> _attr(String name, String value) {
|
||||
addAttr(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generic<Generic<T>> _elem(String name, EnumSet<EOpt> opts) {
|
||||
closeAttrs();
|
||||
return new Generic<Generic<T>>(name, this, opts);
|
||||
}
|
||||
|
||||
public Generic<Generic<T>> elem(String name) {
|
||||
return _elem(name, of(ENDTAG));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generic<T> _(Object... lines) {
|
||||
_p(true, lines);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generic<T> _r(Object... lines) {
|
||||
_p(false, lines);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public HamletImpl(PrintWriter out, int nestLevel, boolean wasInline) {
|
||||
this.out = out;
|
||||
this.nestLevel = nestLevel;
|
||||
this.wasInline = wasInline;
|
||||
}
|
||||
|
||||
public int nestLevel() {
|
||||
return nestLevel;
|
||||
}
|
||||
|
||||
public boolean wasInline() {
|
||||
return wasInline;
|
||||
}
|
||||
|
||||
public void setWasInline(boolean state) {
|
||||
wasInline = state;
|
||||
}
|
||||
|
||||
public PrintWriter getWriter() {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a root-level generic element.
|
||||
* Mostly for testing purpose.
|
||||
* @param <T> type of the parent element
|
||||
* @param name of the element
|
||||
* @param opts {@link EOpt element options}
|
||||
* @return the element
|
||||
*/
|
||||
public <T extends _>
|
||||
Generic<T> root(String name, EnumSet<EOpt> opts) {
|
||||
return new Generic<T>(name, null, opts);
|
||||
}
|
||||
|
||||
public <T extends _> Generic<T> root(String name) {
|
||||
return root(name, of(ENDTAG));
|
||||
}
|
||||
|
||||
protected void printStartTag(String name, EnumSet<EOpt> opts) {
|
||||
indent(opts);
|
||||
sb.setLength(0);
|
||||
out.print(sb.append('<').append(name).toString()); // for easier mock test
|
||||
}
|
||||
|
||||
protected void indent(EnumSet<EOpt> opts) {
|
||||
if (opts.contains(INLINE) && wasInline) {
|
||||
return;
|
||||
}
|
||||
if (wasInline) {
|
||||
out.println();
|
||||
}
|
||||
wasInline = opts.contains(INLINE) || opts.contains(PRE);
|
||||
for (int i = 0; i < nestLevel; ++i) {
|
||||
out.print(INDENT_CHARS);
|
||||
}
|
||||
++indents;
|
||||
}
|
||||
|
||||
protected void printEndTag(String name, EnumSet<EOpt> opts) {
|
||||
if (!opts.contains(ENDTAG)) {
|
||||
return;
|
||||
}
|
||||
if (!opts.contains(PRE)) {
|
||||
indent(opts);
|
||||
} else {
|
||||
wasInline = opts.contains(INLINE);
|
||||
}
|
||||
sb.setLength(0);
|
||||
out.print(sb.append("</").append(name).append('>').toString()); // ditto
|
||||
if (!opts.contains(INLINE)) {
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
protected void printAttr(String name, String value) {
|
||||
sb.setLength(0);
|
||||
sb.append(' ').append(name);
|
||||
if (value != null) {
|
||||
sb.append("=\"").append(escapeHtml4(value)).append("\"");
|
||||
}
|
||||
out.print(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub-classes should override this to do something interesting.
|
||||
* @param cls the sub-view class
|
||||
*/
|
||||
protected void subView(Class<? extends SubView> cls) {
|
||||
indent(of(ENDTAG)); // not an inline view
|
||||
sb.setLength(0);
|
||||
out.print(sb.append('[').append(cls.getName()).append(']').toString());
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse selector into id and classes
|
||||
* @param selector in the form of (#id)?(.class)*
|
||||
* @return an two element array [id, "space-separated classes"].
|
||||
* Either element could be null.
|
||||
* @throws WebAppException when both are null or syntax error.
|
||||
*/
|
||||
public static String[] parseSelector(String selector) {
|
||||
String[] result = new String[]{null, null};
|
||||
Iterable<String> rs = SS.split(selector);
|
||||
Iterator<String> it = rs.iterator();
|
||||
if (it.hasNext()) {
|
||||
String maybeId = it.next();
|
||||
if (maybeId.charAt(0) == '#') {
|
||||
result[S_ID] = maybeId.substring(1);
|
||||
if (it.hasNext()) {
|
||||
result[S_CLASS] = SJ.join(Iterables.skip(rs, 1));
|
||||
}
|
||||
} else {
|
||||
result[S_CLASS] = SJ.join(rs);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
throw new WebAppException("Error parsing selector: "+ selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set id and/or class attributes for an element.
|
||||
* @param <E> type of the element
|
||||
* @param e the element
|
||||
* @param selector Haml form of "(#id)?(.class)*"
|
||||
* @return the element
|
||||
*/
|
||||
public static <E extends CoreAttrs> E setSelector(E e, String selector) {
|
||||
String[] res = parseSelector(selector);
|
||||
if (res[S_ID] != null) {
|
||||
e.$id(res[S_ID]);
|
||||
}
|
||||
if (res[S_CLASS] != null) {
|
||||
e.$class(res[S_CLASS]);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
public static <E extends LINK> E setLinkHref(E e, String href) {
|
||||
if (href.endsWith(".css")) {
|
||||
e.$rel("stylesheet"); // required in html5
|
||||
}
|
||||
e.$href(href);
|
||||
return e;
|
||||
}
|
||||
|
||||
public static <E extends SCRIPT> E setScriptSrc(E e, String src) {
|
||||
if (src.endsWith(".js")) {
|
||||
e.$type("text/javascript"); // required in html4
|
||||
}
|
||||
e.$src(src);
|
||||
return e;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
* Use org.apache.hadoop.yarn.webapp.hamlet2 package instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@InterfaceAudience.LimitedPrivate({"YARN", "MapReduce"})
|
||||
package org.apache.hadoop.yarn.webapp.hamlet;
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
* 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.hadoop.yarn.webapp.hamlet;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.apache.hadoop.yarn.webapp.WebAppException;
|
||||
|
||||
import static org.apache.hadoop.yarn.webapp.hamlet.HamletImpl.*;
|
||||
|
||||
public class TestParseSelector {
|
||||
|
||||
@Test public void testNormal() {
|
||||
String[] res = parseSelector("#id.class");
|
||||
assertEquals("id", res[S_ID]);
|
||||
assertEquals("class", res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test public void testMultiClass() {
|
||||
String[] res = parseSelector("#id.class1.class2");
|
||||
assertEquals("id", res[S_ID]);
|
||||
assertEquals("class1 class2", res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test public void testMissingId() {
|
||||
String[] res = parseSelector(".class");
|
||||
assertNull(res[S_ID]);
|
||||
assertEquals("class", res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test public void testMissingClass() {
|
||||
String[] res = parseSelector("#id");
|
||||
assertEquals("id", res[S_ID]);
|
||||
assertNull(res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test(expected=WebAppException.class) public void testMissingAll() {
|
||||
parseSelector("");
|
||||
}
|
||||
}
|
|
@ -1,33 +1,31 @@
|
|||
/**
|
||||
* 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.hadoop.yarn.webapp.hamlet;
|
||||
/*
|
||||
* 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.hadoop.yarn.webapp.hamlet2;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.io.PrintWriter;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.apache.hadoop.yarn.webapp.SubView;
|
||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
||||
|
||||
import static org.apache.hadoop.yarn.webapp.hamlet.HamletSpec.*;
|
||||
import static org.apache.hadoop.yarn.webapp.hamlet2.HamletSpec.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class TestHamlet {
|
||||
|
||||
|
@ -37,10 +35,10 @@ public class TestHamlet {
|
|||
h1("heading 1").
|
||||
p("#id.class").
|
||||
b("hello").
|
||||
em("world!")._().
|
||||
em("world!").__().
|
||||
div("#footer").
|
||||
_("Brought to you by").
|
||||
a("http://hostname/", "Somebody")._();
|
||||
__("Brought to you by").
|
||||
a("https://hostname/", "Somebody").__();
|
||||
|
||||
PrintWriter out = h.getWriter();
|
||||
out.flush();
|
||||
|
@ -64,7 +62,7 @@ public class TestHamlet {
|
|||
verify(out).print(" id=\"footer\"");
|
||||
verify(out).print("Brought to you by");
|
||||
verify(out).print("<a");
|
||||
verify(out).print(" href=\"http://hostname/\"");
|
||||
verify(out).print(" href=\"https://hostname/\"");
|
||||
verify(out).print("Somebody");
|
||||
verify(out).print("</a>");
|
||||
verify(out).print("</div>");
|
||||
|
@ -79,9 +77,9 @@ public class TestHamlet {
|
|||
TABLE t = h.table("#id");
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
t.tr().td("1").td("2")._();
|
||||
t.tr().td("1").td("2").__();
|
||||
}
|
||||
t._();
|
||||
t.__();
|
||||
|
||||
PrintWriter out = h.getWriter();
|
||||
out.flush();
|
||||
|
@ -98,11 +96,11 @@ public class TestHamlet {
|
|||
title("test enum attrs").
|
||||
link().$rel("stylesheet").
|
||||
$media(EnumSet.of(Media.screen, Media.print)).
|
||||
$type("text/css").$href("style.css")._().
|
||||
$type("text/css").$href("style.css").__().
|
||||
link().$rel(EnumSet.of(LinkType.index, LinkType.start)).
|
||||
$href("index.html")._();
|
||||
$href("index.html").__();
|
||||
|
||||
h.div("#content")._("content")._();
|
||||
h.div("#content").__("content").__();
|
||||
|
||||
PrintWriter out = h.getWriter();
|
||||
out.flush();
|
||||
|
@ -128,10 +126,10 @@ public class TestHamlet {
|
|||
div().
|
||||
i("inline before pre").
|
||||
pre().
|
||||
_("pre text1\npre text2").
|
||||
__("pre text1\npre text2").
|
||||
i("inline in pre").
|
||||
_("pre text after inline")._().
|
||||
i("inline after pre")._();
|
||||
__("pre text after inline").__().
|
||||
i("inline after pre").__();
|
||||
|
||||
PrintWriter out = h.getWriter();
|
||||
out.flush();
|
||||
|
@ -149,8 +147,8 @@ public class TestHamlet {
|
|||
@Test public void testSubViews() {
|
||||
Hamlet h = newHamlet().
|
||||
title("test sub-views").
|
||||
div("#view1")._(TestView1.class)._().
|
||||
div("#view2")._(TestView2.class)._();
|
||||
div("#view1").__(TestView1.class).__().
|
||||
div("#view2").__(TestView2.class).__();
|
||||
|
||||
PrintWriter out = h.getWriter();
|
||||
out.flush();
|
|
@ -1,30 +1,29 @@
|
|||
/**
|
||||
* 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.hadoop.yarn.webapp.hamlet;
|
||||
/*
|
||||
* 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.hadoop.yarn.webapp.hamlet2;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.apache.hadoop.yarn.webapp.hamlet.HamletImpl;
|
||||
import org.apache.hadoop.yarn.webapp.hamlet.HamletSpec.*;
|
||||
import org.apache.hadoop.yarn.webapp.hamlet2.HamletSpec.*;
|
||||
|
||||
public class TestHamletImpl {
|
||||
/**
|
||||
|
@ -36,24 +35,24 @@ public class TestHamletImpl {
|
|||
HamletImpl hi = new HamletImpl(out, 0, false);
|
||||
hi.
|
||||
root("start")._attr("name", "value").
|
||||
_("start text").
|
||||
__("start text").
|
||||
elem("sub")._attr("name", "value").
|
||||
_("sub text")._().
|
||||
__("sub text").__().
|
||||
elem("sub1")._noEndTag()._attr("boolean", null).
|
||||
_("sub1text")._().
|
||||
_("start text2").
|
||||
__("sub1text").__().
|
||||
__("start text2").
|
||||
elem("pre")._pre().
|
||||
_("pre text").
|
||||
elem("i")._inline()._("inline")._()._().
|
||||
elem("i")._inline()._("inline after pre")._().
|
||||
_("start text3").
|
||||
__("pre text").
|
||||
elem("i")._inline().__("inline").__().__().
|
||||
elem("i")._inline().__("inline after pre").__().
|
||||
__("start text3").
|
||||
elem("sub2").
|
||||
_("sub2text")._().
|
||||
__("sub2text").__().
|
||||
elem("sub3")._noEndTag().
|
||||
_("sub3text")._().
|
||||
__("sub3text").__().
|
||||
elem("sub4")._noEndTag().
|
||||
elem("i")._inline()._("inline")._().
|
||||
_("sub4text")._()._();
|
||||
elem("i")._inline().__("inline").__().
|
||||
__("sub4text").__().__();
|
||||
|
||||
out.flush();
|
||||
assertEquals(0, hi.nestLevel);
|
||||
|
@ -75,11 +74,11 @@ public class TestHamletImpl {
|
|||
verify(e).$class("class");
|
||||
|
||||
H1 t = mock(H1.class);
|
||||
HamletImpl.setSelector(t, "#id.class")._("heading");
|
||||
HamletImpl.setSelector(t, "#id.class").__("heading");
|
||||
|
||||
verify(t).$id("id");
|
||||
verify(t).$class("class");
|
||||
verify(t)._("heading");
|
||||
verify(t).__("heading");
|
||||
}
|
||||
|
||||
@Test public void testSetLinkHref() {
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.hadoop.yarn.webapp.hamlet2;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.apache.hadoop.yarn.webapp.hamlet2.HamletImpl.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.apache.hadoop.yarn.webapp.WebAppException;
|
||||
|
||||
public class TestParseSelector {
|
||||
|
||||
@Test public void testNormal() {
|
||||
String[] res = parseSelector("#id.class");
|
||||
assertEquals("id", res[S_ID]);
|
||||
assertEquals("class", res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test public void testMultiClass() {
|
||||
String[] res = parseSelector("#id.class1.class2");
|
||||
assertEquals("id", res[S_ID]);
|
||||
assertEquals("class1 class2", res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test public void testMissingId() {
|
||||
String[] res = parseSelector(".class");
|
||||
assertNull(res[S_ID]);
|
||||
assertEquals("class", res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test public void testMissingClass() {
|
||||
String[] res = parseSelector("#id");
|
||||
assertEquals("id", res[S_ID]);
|
||||
assertNull(res[S_CLASS]);
|
||||
}
|
||||
|
||||
@Test(expected=WebAppException.class) public void testMissingAll() {
|
||||
parseSelector("");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue