This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
/*
* 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.tomcat.util.descriptor.tld;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.digester.Rule;
import org.apache.tomcat.util.digester.RuleSetBase;
import org.apache.tomcat.util.res.StringManager;
import org.xml.sax.Attributes;
/**
* RulesSet for digesting implicit.tld files.
*
* Only version information used and short names are allowed.
*/
@SuppressWarnings("deprecation")
public class ImplicitTldRuleSet extends RuleSetBase {
private static final StringManager sm = StringManager.getManager(ImplicitTldRuleSet.class);
private static final String PREFIX = "taglib";
private static final String VALIDATOR_PREFIX = PREFIX + "/validator";
private static final String TAG_PREFIX = PREFIX + "/tag";
private static final String TAGFILE_PREFIX = PREFIX + "/tag-file";
private static final String FUNCTION_PREFIX = PREFIX + "/function";
@Override
public void addRuleInstances(Digester digester) {
digester.addCallMethod(PREFIX + "/tlibversion", "setTlibVersion", 0);
digester.addCallMethod(PREFIX + "/tlib-version", "setTlibVersion", 0);
digester.addCallMethod(PREFIX + "/jspversion", "setJspVersion", 0);
digester.addCallMethod(PREFIX + "/jsp-version", "setJspVersion", 0);
digester.addRule(PREFIX, new Rule() {
// for TLD 2.0 and later, jsp-version is set by version attribute
@Override
public void begin(String namespace, String name, Attributes attributes) {
TaglibXml taglibXml = (TaglibXml) digester.peek();
taglibXml.setJspVersion(attributes.getValue("version"));
}
});
digester.addCallMethod(PREFIX + "/shortname", "setShortName", 0);
digester.addCallMethod(PREFIX + "/short-name", "setShortName", 0);
// Elements not permitted
digester.addRule(PREFIX + "/uri", new ElementNotAllowedRule());
digester.addRule(PREFIX + "/info", new ElementNotAllowedRule());
digester.addRule(PREFIX + "/description", new ElementNotAllowedRule());
digester.addRule(PREFIX + "/listener/listener-class", new ElementNotAllowedRule());
digester.addRule(VALIDATOR_PREFIX, new ElementNotAllowedRule());
digester.addRule(TAG_PREFIX, new ElementNotAllowedRule());
digester.addRule(TAGFILE_PREFIX, new ElementNotAllowedRule());
digester.addRule(FUNCTION_PREFIX, new ElementNotAllowedRule());
}
private static class ElementNotAllowedRule extends Rule {
@Override
public void begin(String namespace, String name, Attributes attributes) throws Exception {
throw new IllegalArgumentException(
sm.getString("implicitTldRule.elementNotAllowed", name));
}
}
}

View File

@@ -0,0 +1,16 @@
# 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.
implicitTldRule.elementNotAllowed=The element [{0}] is not permitted in an implicit.tld file

View File

@@ -0,0 +1,16 @@
# 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.
implicitTldRule.elementNotAllowed=L''élément [{0}] n''est pas autorisé dans un fichier TLD implicite

View File

@@ -0,0 +1,16 @@
# 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.
implicitTldRule.elementNotAllowed=要素[{0}]は、implicit.tldファイルでは許可されていません。

View File

@@ -0,0 +1,16 @@
# 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.
implicitTldRule.elementNotAllowed=implicit.tld 파일 내에서, 엘리먼트 [{0}]은(는) 허용되지 않습니다.

View File

@@ -0,0 +1,79 @@
/*
* 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.tomcat.util.descriptor.tld;
/**
* Bare-bone model of a tag file loaded from a TLD.
* This does not contain the tag-specific attributes that requiring parsing
* the actual tag file to derive.
*/
public class TagFileXml {
private String name;
private String path;
private String displayName;
private String smallIcon;
private String largeIcon;
private String info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getSmallIcon() {
return smallIcon;
}
public void setSmallIcon(String smallIcon) {
this.smallIcon = smallIcon;
}
public String getLargeIcon() {
return largeIcon;
}
public void setLargeIcon(String largeIcon) {
this.largeIcon = largeIcon;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}

View File

@@ -0,0 +1,124 @@
/*
* 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.tomcat.util.descriptor.tld;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.jsp.tagext.TagAttributeInfo;
import javax.servlet.jsp.tagext.TagInfo;
import javax.servlet.jsp.tagext.TagVariableInfo;
/**
* Model of a tag define in a tag library descriptor.
* This represents the information as parsed from the XML but differs from
* TagInfo in that is does not provide a link back to the tag library that
* defined it.
*/
public class TagXml {
private String name;
private String tagClass;
private String teiClass;
private String bodyContent = TagInfo.BODY_CONTENT_JSP;
private String displayName;
private String smallIcon;
private String largeIcon;
private String info;
private boolean dynamicAttributes;
private final List<TagAttributeInfo> attributes = new ArrayList<>();
private final List<TagVariableInfo> variables = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTagClass() {
return tagClass;
}
public void setTagClass(String tagClass) {
this.tagClass = tagClass;
}
public String getTeiClass() {
return teiClass;
}
public void setTeiClass(String teiClass) {
this.teiClass = teiClass;
}
public String getBodyContent() {
return bodyContent;
}
public void setBodyContent(String bodyContent) {
this.bodyContent = bodyContent;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getSmallIcon() {
return smallIcon;
}
public void setSmallIcon(String smallIcon) {
this.smallIcon = smallIcon;
}
public String getLargeIcon() {
return largeIcon;
}
public void setLargeIcon(String largeIcon) {
this.largeIcon = largeIcon;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public boolean hasDynamicAttributes() {
return dynamicAttributes;
}
public void setDynamicAttributes(boolean dynamicAttributes) {
this.dynamicAttributes = dynamicAttributes;
}
public List<TagAttributeInfo> getAttributes() {
return attributes;
}
public List<TagVariableInfo> getVariables() {
return variables;
}
}

View File

@@ -0,0 +1,124 @@
/*
* 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.tomcat.util.descriptor.tld;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.jsp.tagext.FunctionInfo;
/**
* Common representation of a Tag Library Descriptor (TLD) XML file.
* <p>
* This stores the raw result of parsing an TLD XML file, flattening different
* version of the descriptors to a common format. This is different to a
* TagLibraryInfo instance that would be passed to a tag validator in that it
* does not contain the uri and prefix values used by a JSP to reference this
* tag library.
*/
public class TaglibXml {
private String tlibVersion;
private String jspVersion;
private String shortName;
private String uri;
private String info;
private ValidatorXml validator;
private final List<TagXml> tags = new ArrayList<>();
private final List<TagFileXml> tagFiles = new ArrayList<>();
private final List<String> listeners = new ArrayList<>();
private final List<FunctionInfo> functions = new ArrayList<>();
public String getTlibVersion() {
return tlibVersion;
}
public void setTlibVersion(String tlibVersion) {
this.tlibVersion = tlibVersion;
}
public String getJspVersion() {
return jspVersion;
}
public void setJspVersion(String jspVersion) {
this.jspVersion = jspVersion;
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public ValidatorXml getValidator() {
return validator;
}
public void setValidator(ValidatorXml validator) {
this.validator = validator;
}
public void addTag(TagXml tag) {
tags.add(tag);
}
public List<TagXml> getTags() {
return tags;
}
public void addTagFile(TagFileXml tag) {
tagFiles.add(tag);
}
public List<TagFileXml> getTagFiles() {
return tagFiles;
}
public void addListener(String listener) {
listeners.add(listener);
}
public List<String> getListeners() {
return listeners;
}
public void addFunction(String name, String klass, String signature) {
functions.add(new FunctionInfo(name, klass, signature));
}
public List<FunctionInfo> getFunctions() {
return functions;
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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.tomcat.util.descriptor.tld;
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessController;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.descriptor.Constants;
import org.apache.tomcat.util.descriptor.DigesterFactory;
import org.apache.tomcat.util.descriptor.XmlErrorHandler;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.digester.RuleSet;
import org.apache.tomcat.util.security.PrivilegedGetTccl;
import org.apache.tomcat.util.security.PrivilegedSetTccl;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Parses a Tag Library Descriptor.
*/
public class TldParser {
private final Log log = LogFactory.getLog(TldParser.class); // must not be static
private final Digester digester;
public TldParser(boolean namespaceAware, boolean validation,
boolean blockExternal) {
this(namespaceAware, validation, new TldRuleSet(), blockExternal);
}
public TldParser(boolean namespaceAware, boolean validation, RuleSet ruleSet,
boolean blockExternal) {
digester = DigesterFactory.newDigester(
validation, namespaceAware, ruleSet, blockExternal);
}
public TaglibXml parse(TldResourcePath path) throws IOException, SAXException {
ClassLoader original;
if (Constants.IS_SECURITY_ENABLED) {
PrivilegedGetTccl pa = new PrivilegedGetTccl();
original = AccessController.doPrivileged(pa);
} else {
original = Thread.currentThread().getContextClassLoader();
}
try (InputStream is = path.openStream()) {
if (Constants.IS_SECURITY_ENABLED) {
PrivilegedSetTccl pa = new PrivilegedSetTccl(TldParser.class.getClassLoader());
AccessController.doPrivileged(pa);
} else {
Thread.currentThread().setContextClassLoader(TldParser.class.getClassLoader());
}
XmlErrorHandler handler = new XmlErrorHandler();
digester.setErrorHandler(handler);
TaglibXml taglibXml = new TaglibXml();
digester.push(taglibXml);
InputSource source = new InputSource(path.toExternalForm());
source.setByteStream(is);
digester.parse(source);
if (!handler.getWarnings().isEmpty() || !handler.getErrors().isEmpty()) {
handler.logFindings(log, source.getSystemId());
if (!handler.getErrors().isEmpty()) {
// throw the first to indicate there was an error during processing
throw handler.getErrors().iterator().next();
}
}
return taglibXml;
} finally {
digester.reset();
if (Constants.IS_SECURITY_ENABLED) {
PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
AccessController.doPrivileged(pa);
} else {
Thread.currentThread().setContextClassLoader(original);
}
}
}
public void setClassLoader(ClassLoader classLoader) {
digester.setClassLoader(classLoader);
}
}

View File

@@ -0,0 +1,171 @@
/*
* 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.tomcat.util.descriptor.tld;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Objects;
import org.apache.tomcat.Jar;
import org.apache.tomcat.util.scan.JarFactory;
import org.apache.tomcat.util.scan.ReferenceCountedJar;
/**
* A TLD Resource Path as defined in JSP 7.3.2.
* <p>
* This encapsulates references to Tag Library Descriptors that can be located
* in different places:
* <ul>
* <li>As resources within an application</li>
* <li>As entries in JAR files included in the application</li>
* <li>As resources provided by the container</li>
* </ul>
* When configuring a mapping from a well-known URI to a TLD, a user is allowed
* to specify just the name of a JAR file that implicitly contains a TLD in
* <code>META-INF/taglib.tld</code>. Such a mapping must be explicitly converted
* to a URL and entryName when using this implementation.
*/
public class TldResourcePath {
private final URL url;
private final String webappPath;
private final String entryName;
/**
* Constructor identifying a TLD resource directly.
*
* @param url the location of the TLD
* @param webappPath the web application path, if any, of the TLD
*/
public TldResourcePath(URL url, String webappPath) {
this(url, webappPath, null);
}
/**
* Constructor identifying a TLD packaged within a JAR file.
*
* @param url the location of the JAR
* @param webappPath the web application path, if any, of the JAR
* @param entryName the name of the entry in the JAR
*/
public TldResourcePath(URL url, String webappPath, String entryName) {
this.url = url;
this.webappPath = webappPath;
this.entryName = entryName;
}
/**
* Returns the URL of the TLD or of the JAR containing the TLD.
*
* @return the URL of the TLD
*/
public URL getUrl() {
return url;
}
/**
* Returns the path within the web application, if any, that the resource
* returned by {@link #getUrl()} was obtained from.
*
* @return the web application path or @null if the the resource is not
* located within a web application
*/
public String getWebappPath() {
return webappPath;
}
/**
* Returns the name of the JAR entry that contains the TLD.
* May be null to indicate the URL refers directly to the TLD itself.
*
* @return the name of the JAR entry that contains the TLD
*/
public String getEntryName() {
return entryName;
}
/**
* Return the external form of the URL representing this TLD.
* This can be used as a canonical location for the TLD itself, for example,
* as the systemId to use when parsing its XML.
*
* @return the external form of the URL representing this TLD
*/
public String toExternalForm() {
if (entryName == null) {
return url.toExternalForm();
} else {
return "jar:" + url.toExternalForm() + "!/" + entryName;
}
}
/**
* Opens a stream to access the TLD.
*
* @return a stream containing the TLD content
* @throws IOException if there was a problem opening the stream
*/
public InputStream openStream() throws IOException {
if (entryName == null) {
return url.openStream();
} else {
URL entryUrl = JarFactory.getJarEntryURL(url, entryName);
return entryUrl.openStream();
}
}
public Jar openJar() throws IOException {
if (entryName == null) {
return null;
} else {
// Bug 62976
// Jar files containing tags are typically opened during initial
// compilation and then closed when compilation is complete. The
// reference counting wrapper is used because, when background
// compilation is enabled, the Jar will need to be accessed (to
// check for modifications) after it has been closed at the end
// of the compilation stage.
// Using a reference counted Jar enables the Jar to be re-opened,
// used and then closed again rather than triggering an ISE.
return new ReferenceCountedJar(url);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TldResourcePath other = (TldResourcePath) o;
return url.equals(other.url) &&
Objects.equals(webappPath, other.webappPath) &&
Objects.equals(entryName, other.entryName);
}
@Override
public int hashCode() {
int result = url.hashCode();
result = result * 31 + Objects.hashCode(webappPath);
result = result * 31 + Objects.hashCode(entryName);
return result;
}
}

View File

@@ -0,0 +1,362 @@
/*
* 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.tomcat.util.descriptor.tld;
import java.lang.reflect.Method;
import javax.servlet.jsp.tagext.TagAttributeInfo;
import javax.servlet.jsp.tagext.TagVariableInfo;
import javax.servlet.jsp.tagext.VariableInfo;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.digester.Rule;
import org.apache.tomcat.util.digester.RuleSetBase;
import org.xml.sax.Attributes;
/**
* RulesSet for digesting TLD files.
*/
@SuppressWarnings("deprecation")
public class TldRuleSet extends RuleSetBase {
private static final String PREFIX = "taglib";
private static final String VALIDATOR_PREFIX = PREFIX + "/validator";
private static final String TAG_PREFIX = PREFIX + "/tag";
private static final String TAGFILE_PREFIX = PREFIX + "/tag-file";
private static final String FUNCTION_PREFIX = PREFIX + "/function";
@Override
public void addRuleInstances(Digester digester) {
digester.addCallMethod(PREFIX + "/tlibversion", "setTlibVersion", 0);
digester.addCallMethod(PREFIX + "/tlib-version", "setTlibVersion", 0);
digester.addCallMethod(PREFIX + "/jspversion", "setJspVersion", 0);
digester.addCallMethod(PREFIX + "/jsp-version", "setJspVersion", 0);
digester.addRule(PREFIX, new Rule() {
// for TLD 2.0 and later, jsp-version is set by version attribute
@Override
public void begin(String namespace, String name, Attributes attributes) {
TaglibXml taglibXml = (TaglibXml) digester.peek();
taglibXml.setJspVersion(attributes.getValue("version"));
}
});
digester.addCallMethod(PREFIX + "/shortname", "setShortName", 0);
digester.addCallMethod(PREFIX + "/short-name", "setShortName", 0);
// common rules
digester.addCallMethod(PREFIX + "/uri", "setUri", 0);
digester.addCallMethod(PREFIX + "/info", "setInfo", 0);
digester.addCallMethod(PREFIX + "/description", "setInfo", 0);
digester.addCallMethod(PREFIX + "/listener/listener-class", "addListener", 0);
// validator
digester.addObjectCreate(VALIDATOR_PREFIX, ValidatorXml.class.getName());
digester.addCallMethod(VALIDATOR_PREFIX + "/validator-class", "setValidatorClass", 0);
digester.addCallMethod(VALIDATOR_PREFIX + "/init-param", "addInitParam", 2);
digester.addCallParam(VALIDATOR_PREFIX + "/init-param/param-name", 0);
digester.addCallParam(VALIDATOR_PREFIX + "/init-param/param-value", 1);
digester.addSetNext(VALIDATOR_PREFIX, "setValidator", ValidatorXml.class.getName());
// tag
digester.addObjectCreate(TAG_PREFIX, TagXml.class.getName());
addDescriptionGroup(digester, TAG_PREFIX);
digester.addCallMethod(TAG_PREFIX + "/name", "setName", 0);
digester.addCallMethod(TAG_PREFIX + "/tagclass", "setTagClass", 0);
digester.addCallMethod(TAG_PREFIX + "/tag-class", "setTagClass", 0);
digester.addCallMethod(TAG_PREFIX + "/teiclass", "setTeiClass", 0);
digester.addCallMethod(TAG_PREFIX + "/tei-class", "setTeiClass", 0);
digester.addCallMethod(TAG_PREFIX + "/bodycontent", "setBodyContent", 0);
digester.addCallMethod(TAG_PREFIX + "/body-content", "setBodyContent", 0);
digester.addRule(TAG_PREFIX + "/variable", new ScriptVariableRule());
digester.addCallMethod(TAG_PREFIX + "/variable/name-given", "setNameGiven", 0);
digester.addCallMethod(TAG_PREFIX + "/variable/name-from-attribute",
"setNameFromAttribute", 0);
digester.addCallMethod(TAG_PREFIX + "/variable/variable-class", "setClassName", 0);
digester.addRule(TAG_PREFIX + "/variable/declare",
new GenericBooleanRule(Variable.class, "setDeclare"));
digester.addCallMethod(TAG_PREFIX + "/variable/scope", "setScope", 0);
digester.addRule(TAG_PREFIX + "/attribute", new TagAttributeRule());
digester.addCallMethod(TAG_PREFIX + "/attribute/description", "setDescription", 0);
digester.addCallMethod(TAG_PREFIX + "/attribute/name", "setName", 0);
digester.addRule(TAG_PREFIX + "/attribute/required",
new GenericBooleanRule(Attribute.class, "setRequired"));
digester.addRule(TAG_PREFIX + "/attribute/rtexprvalue",
new GenericBooleanRule(Attribute.class, "setRequestTime"));
digester.addCallMethod(TAG_PREFIX + "/attribute/type", "setType", 0);
digester.addCallMethod(TAG_PREFIX + "/attribute/deferred-value", "setDeferredValue");
digester.addCallMethod(TAG_PREFIX + "/attribute/deferred-value/type",
"setExpectedTypeName", 0);
digester.addCallMethod(TAG_PREFIX + "/attribute/deferred-method", "setDeferredMethod");
digester.addCallMethod(TAG_PREFIX + "/attribute/deferred-method/method-signature",
"setMethodSignature", 0);
digester.addRule(TAG_PREFIX + "/attribute/fragment",
new GenericBooleanRule(Attribute.class, "setFragment"));
digester.addRule(TAG_PREFIX + "/dynamic-attributes",
new GenericBooleanRule(TagXml.class, "setDynamicAttributes"));
digester.addSetNext(TAG_PREFIX, "addTag", TagXml.class.getName());
// tag-file
digester.addObjectCreate(TAGFILE_PREFIX, TagFileXml.class.getName());
addDescriptionGroup(digester, TAGFILE_PREFIX);
digester.addCallMethod(TAGFILE_PREFIX + "/name", "setName", 0);
digester.addCallMethod(TAGFILE_PREFIX + "/path", "setPath", 0);
digester.addSetNext(TAGFILE_PREFIX, "addTagFile", TagFileXml.class.getName());
// function
digester.addCallMethod(FUNCTION_PREFIX, "addFunction", 3);
digester.addCallParam(FUNCTION_PREFIX + "/name", 0);
digester.addCallParam(FUNCTION_PREFIX + "/function-class", 1);
digester.addCallParam(FUNCTION_PREFIX + "/function-signature", 2);
}
private void addDescriptionGroup(Digester digester, String prefix) {
digester.addCallMethod(prefix + "/info", "setInfo", 0);
digester.addCallMethod(prefix + "small-icon", "setSmallIcon", 0);
digester.addCallMethod(prefix + "large-icon", "setLargeIcon", 0);
digester.addCallMethod(prefix + "/description", "setInfo", 0);
digester.addCallMethod(prefix + "/display-name", "setDisplayName", 0);
digester.addCallMethod(prefix + "/icon/small-icon", "setSmallIcon", 0);
digester.addCallMethod(prefix + "/icon/large-icon", "setLargeIcon", 0);
}
private static class TagAttributeRule extends Rule {
@Override
public void begin(String namespace, String name, Attributes attributes) throws Exception {
TaglibXml taglibXml = (TaglibXml) digester.peek(digester.getCount() - 1);
digester.push(new Attribute("1.2".equals(taglibXml.getJspVersion())));
}
@Override
public void end(String namespace, String name) throws Exception {
Attribute attribute = (Attribute) digester.pop();
TagXml tag = (TagXml) digester.peek();
tag.getAttributes().add(attribute.toTagAttributeInfo());
}
}
public static class Attribute {
private final boolean allowShortNames;
private String name;
private boolean required;
private String type;
private boolean requestTime;
private boolean fragment;
private String description;
private boolean deferredValue;
private boolean deferredMethod;
private String expectedTypeName;
private String methodSignature;
private Attribute(boolean allowShortNames) {
this.allowShortNames = allowShortNames;
}
public void setName(String name) {
this.name = name;
}
public void setRequired(boolean required) {
this.required = required;
}
public void setType(String type) {
if (allowShortNames) {
switch (type) {
case "Boolean":
this.type = "java.lang.Boolean";
break;
case "Character":
this.type = "java.lang.Character";
break;
case "Byte":
this.type = "java.lang.Byte";
break;
case "Short":
this.type = "java.lang.Short";
break;
case "Integer":
this.type = "java.lang.Integer";
break;
case "Long":
this.type = "java.lang.Long";
break;
case "Float":
this.type = "java.lang.Float";
break;
case "Double":
this.type = "java.lang.Double";
break;
case "String":
this.type = "java.lang.String";
break;
case "Object":
this.type = "java.lang.Object";
break;
default:
this.type = type;
break;
}
} else {
this.type = type;
}
}
public void setRequestTime(boolean requestTime) {
this.requestTime = requestTime;
}
public void setFragment(boolean fragment) {
this.fragment = fragment;
}
public void setDescription(String description) {
this.description = description;
}
public void setDeferredValue() {
this.deferredValue = true;
}
public void setDeferredMethod() {
this.deferredMethod = true;
}
public void setExpectedTypeName(String expectedTypeName) {
this.expectedTypeName = expectedTypeName;
}
public void setMethodSignature(String methodSignature) {
this.methodSignature = methodSignature;
}
public TagAttributeInfo toTagAttributeInfo() {
if (fragment) {
// JSP8.5.2: for a fragment type is fixed and rexprvalue is true
type = "javax.servlet.jsp.tagext.JspFragment";
requestTime = true;
} else if (deferredValue) {
type = "javax.el.ValueExpression";
if (expectedTypeName == null) {
expectedTypeName = "java.lang.Object";
}
} else if (deferredMethod) {
type = "javax.el.MethodExpression";
if (methodSignature == null) {
methodSignature = "java.lang.Object method()";
}
}
// According to JSP spec, for static values (those determined at
// translation time) the type is fixed at java.lang.String.
if (!requestTime && type == null) {
type = "java.lang.String";
}
return new TagAttributeInfo(
name,
required,
type,
requestTime,
fragment,
description,
deferredValue,
deferredMethod,
expectedTypeName,
methodSignature);
}
}
private static class ScriptVariableRule extends Rule {
@Override
public void begin(String namespace, String name, Attributes attributes) throws Exception {
digester.push(new Variable());
}
@Override
public void end(String namespace, String name) throws Exception {
Variable variable = (Variable) digester.pop();
TagXml tag = (TagXml) digester.peek();
tag.getVariables().add(variable.toTagVariableInfo());
}
}
public static class Variable {
private String nameGiven;
private String nameFromAttribute;
private String className = "java.lang.String";
private boolean declare = true;
private int scope = VariableInfo.NESTED;
public void setNameGiven(String nameGiven) {
this.nameGiven = nameGiven;
}
public void setNameFromAttribute(String nameFromAttribute) {
this.nameFromAttribute = nameFromAttribute;
}
public void setClassName(String className) {
this.className = className;
}
public void setDeclare(boolean declare) {
this.declare = declare;
}
public void setScope(String scopeName) {
switch (scopeName) {
case "NESTED":
scope = VariableInfo.NESTED;
break;
case "AT_BEGIN":
scope = VariableInfo.AT_BEGIN;
break;
case "AT_END":
scope = VariableInfo.AT_END;
break;
}
}
public TagVariableInfo toTagVariableInfo() {
return new TagVariableInfo(nameGiven, nameFromAttribute, className, declare, scope);
}
}
private static class GenericBooleanRule extends Rule {
private final Method setter;
private GenericBooleanRule(Class<?> type, String setterName) {
try {
this.setter = type.getMethod(setterName, Boolean.TYPE);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public void body(String namespace, String name, String text) throws Exception {
if(null != text)
text = text.trim();
boolean value = "true".equalsIgnoreCase(text) || "yes".equalsIgnoreCase(text);
setter.invoke(digester.peek(), Boolean.valueOf(value));
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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.tomcat.util.descriptor.tld;
import java.util.HashMap;
import java.util.Map;
/**
* Model of a Tag Library Validator from the XML descriptor.
*/
public class ValidatorXml {
private String validatorClass;
private final Map<String, String> initParams = new HashMap<>();
public String getValidatorClass() {
return validatorClass;
}
public void setValidatorClass(String validatorClass) {
this.validatorClass = validatorClass;
}
public void addInitParam(String name, String value) {
initParams.put(name, value);
}
public Map<String, String> getInitParams() {
return initParams;
}
}

View File

@@ -0,0 +1,21 @@
/*
* 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 containing a Java model of the XML for a Tag Library Descriptor.
*/
package org.apache.tomcat.util.descriptor.tld;