mirror of
https://github.com/apache/struts.git
synced 2026-08-06 07:06:58 +00:00
WN-5141
- removal of "embedded jsp" plugin (deprecated)
This commit is contained in:
@@ -216,11 +216,6 @@
|
||||
<artifactId>struts2-json-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-embeddedjsp-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-gxp-plugin</artifactId>
|
||||
|
||||
@@ -133,10 +133,6 @@
|
||||
<directory>../plugins/convention/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-convention-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/embeddedjsp/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-embeddedjsp-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/gxp/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-gxp-plugin/apidocs</outputDirectory>
|
||||
|
||||
@@ -68,10 +68,6 @@
|
||||
<directory>../plugins/convention/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-convention-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/embeddedjsp/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-embeddedjsp-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/gxp/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-gxp-plugin/apidocs</outputDirectory>
|
||||
|
||||
@@ -81,11 +81,6 @@
|
||||
<artifactId>struts2-config-browser-plugin</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-embeddedjsp-plugin</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-gxp-plugin</artifactId>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# Struts 2 EmbeddedJSP plugin
|
||||
This plugin is deprecated and it will be removed soon, **please do not use it**!
|
||||
@@ -1,102 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-embeddedjsp-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>DEPRECATED: Struts 2 Embedded JSP Plugin, since 6.0.0</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-plugin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>taglibs</groupId>
|
||||
<artifactId>request</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-juli</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.web</groupId>
|
||||
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet.jsp.jstl</groupId>
|
||||
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-jasper</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine}</argLine>
|
||||
<additionalClasspathElements>
|
||||
<element>${project.build.testOutputDirectory}/jsps.jar</element>
|
||||
</additionalClasspathElements>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</project>
|
||||
@@ -1,32 +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.struts2;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.result.StrutsResultSupport;
|
||||
|
||||
/**
|
||||
* Can render jsps from the classpath. "includes" in the jsps must not use relative paths
|
||||
*/
|
||||
public class EmbeddedJSPResult extends StrutsResultSupport {
|
||||
protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
|
||||
JSPRuntime.handle(StringUtils.removeStart(finalLocation, "/"));
|
||||
}
|
||||
}
|
||||
@@ -1,271 +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.struts2;
|
||||
|
||||
import com.opensymphony.xwork2.FileManager;
|
||||
import com.opensymphony.xwork2.FileManagerFactory;
|
||||
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
|
||||
import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
|
||||
import com.opensymphony.xwork2.util.finder.UrlSet;
|
||||
import com.opensymphony.xwork2.util.fs.DefaultFileManager;
|
||||
import com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.compiler.MemoryClassLoader;
|
||||
import org.apache.struts2.compiler.MemoryJavaFileObject;
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
import org.apache.struts2.jasper.JspC;
|
||||
|
||||
import jakarta.servlet.Servlet;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.jsp.JspPage;
|
||||
import javax.tools.DiagnosticCollector;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.ForwardingJavaFileManager;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.security.CodeSource;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Uses jasper to extract a JSP from the classpath to a file and compile it. The classpath used for
|
||||
* compilation is built by finding all the jar files using the current class loader (Thread), plus
|
||||
* directories.
|
||||
*/
|
||||
public class JSPLoader {
|
||||
private static final Logger LOG = LogManager.getLogger(JSPLoader.class);
|
||||
|
||||
private static MemoryClassLoader classLoader = new MemoryClassLoader();
|
||||
private static final String DEFAULT_PACKAGE = "org.apache.struts2.jsp";
|
||||
|
||||
private static final Pattern PACKAGE_PATTERN = Pattern.compile("package (.*?);");
|
||||
private static final Pattern CLASS_PATTERN = Pattern.compile("public final class (.*?) ");
|
||||
|
||||
public Servlet load(String location) throws Exception {
|
||||
location = StringUtils.substringBeforeLast(location, "?");
|
||||
|
||||
LOG.debug("Compiling JSP [{}]", location);
|
||||
|
||||
//use Jasper to compile the JSP into java code
|
||||
JspC jspC = compileJSP(location);
|
||||
String source = jspC.getSourceCode();
|
||||
|
||||
//System.out.print(source);
|
||||
|
||||
String className = extractClassName(source);
|
||||
|
||||
//use Java Compiler API to compile the java code into a class
|
||||
//the tlds that were discovered are added (their jars) to the classpath
|
||||
compileJava(className, source, jspC.getTldAbsolutePaths());
|
||||
|
||||
//load the class that was just built
|
||||
Class clazz = Class.forName(className, false, classLoader);
|
||||
return createServlet(clazz);
|
||||
}
|
||||
|
||||
private String extractClassName(String source) {
|
||||
Matcher matcher = PACKAGE_PATTERN.matcher(source);
|
||||
matcher.find();
|
||||
String packageName = matcher.group(1);
|
||||
|
||||
matcher = CLASS_PATTERN.matcher(source);
|
||||
matcher.find();
|
||||
String className = matcher.group(1);
|
||||
|
||||
return packageName + "." + className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and inits a servlet
|
||||
*/
|
||||
private Servlet createServlet(Class clazz) throws IllegalAccessException, InstantiationException, ServletException {
|
||||
JSPServletConfig config = new JSPServletConfig(ServletActionContext.getServletContext());
|
||||
|
||||
Servlet servlet = (Servlet) clazz.newInstance();
|
||||
servlet.init(config);
|
||||
|
||||
/*
|
||||
there is no need to call JspPage.init explicitly because Jasper's
|
||||
JSP base classe HttpJspBase.init(ServletConfig) calls:
|
||||
jspInit();
|
||||
_jspInit();
|
||||
*/
|
||||
|
||||
return servlet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the given source code into java bytecode
|
||||
*/
|
||||
private void compileJava(String className, final String source, Set<String> extraClassPath) throws IOException {
|
||||
LOG.trace("Compiling [{}], source: [{}]", className, source);
|
||||
|
||||
JavaCompiler compiler =ToolProvider.getSystemJavaCompiler();
|
||||
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
|
||||
|
||||
//the generated bytecode is fed to the class loader
|
||||
JavaFileManager jfm = new
|
||||
ForwardingJavaFileManager<StandardJavaFileManager>(
|
||||
compiler.getStandardFileManager(diagnostics, null, null)) {
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(Location location,
|
||||
String name,
|
||||
JavaFileObject.Kind kind,
|
||||
FileObject sibling) throws IOException {
|
||||
MemoryJavaFileObject fileObject = new MemoryJavaFileObject(name, kind);
|
||||
classLoader.addMemoryJavaFileObject(name, fileObject);
|
||||
return fileObject;
|
||||
}
|
||||
};
|
||||
|
||||
//read java source code from memory
|
||||
String fileName = className.replace('.', '/') + ".java";
|
||||
SimpleJavaFileObject sourceCodeObject = new SimpleJavaFileObject(toURI(fileName), JavaFileObject.Kind.SOURCE) {
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean
|
||||
ignoreEncodingErrors)
|
||||
throws IOException, IllegalStateException,
|
||||
UnsupportedOperationException {
|
||||
return source;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//build classpath
|
||||
//some entries will be added multiple times, hence the set
|
||||
List<String> optionList = new ArrayList<String>();
|
||||
Set<String> classPath = new HashSet<String>();
|
||||
|
||||
//find available jars
|
||||
ClassLoaderInterface classLoaderInterface = getClassLoaderInterface();
|
||||
UrlSet urlSet = new UrlSet(classLoaderInterface);
|
||||
|
||||
//find jars
|
||||
List<URL> urls = urlSet.getUrls();
|
||||
|
||||
if (urls != null && urls.size() > 0) {
|
||||
final FileManagerFactory fileManagerFactoryGetInstance = ServletActionContext.getActionContext().getInstance(FileManagerFactory.class);
|
||||
final FileManagerFactory contextFileManagerFactory = (fileManagerFactoryGetInstance != null ? fileManagerFactoryGetInstance : (FileManagerFactory) ServletActionContext.getActionContext().get(StrutsConstants.STRUTS_FILE_MANAGER_FACTORY));
|
||||
final FileManagerFactory fileManagerFactory = (contextFileManagerFactory != null ? contextFileManagerFactory : new DefaultFileManagerFactory());
|
||||
final FileManager fileManagerGetInstance = fileManagerFactory.getFileManager();
|
||||
final FileManager contextFileManager = (fileManagerGetInstance != null ? fileManagerGetInstance : (FileManager) ServletActionContext.getActionContext().get(StrutsConstants.STRUTS_FILE_MANAGER));
|
||||
final FileManager fileManager = (contextFileManager != null ? contextFileManager : new DefaultFileManager());
|
||||
for (URL url : urls) {
|
||||
URL normalizedUrl = fileManager.normalizeToFileProtocol(url);
|
||||
File file = FileUtils.toFile(ObjectUtils.defaultIfNull(normalizedUrl, url));
|
||||
if (file.exists())
|
||||
classPath.add(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
//these should be in the list already, but I am feeling paranoid
|
||||
//this jar
|
||||
classPath.add(getJarUrl(EmbeddedJSPResult.class));
|
||||
//servlet api
|
||||
classPath.add(getJarUrl(Servlet.class));
|
||||
//jsp api
|
||||
classPath.add(getJarUrl(JspPage.class));
|
||||
|
||||
try {
|
||||
Class instanceManager = Class.forName("org.apache.tomcat.InstanceManager");
|
||||
classPath.add(getJarUrl(instanceManager));
|
||||
} catch (ClassNotFoundException e) {
|
||||
//ok ignore
|
||||
}
|
||||
|
||||
//add extra classpath entries (jars where tlds were found will be here)
|
||||
for (Iterator<String> iterator = extraClassPath.iterator(); iterator.hasNext();) {
|
||||
String entry = iterator.next();
|
||||
classPath.add(entry);
|
||||
}
|
||||
|
||||
String classPathString = StringUtils.join(classPath, File.pathSeparator);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Compiling [#0] with classpath [#1]", className, classPathString);
|
||||
}
|
||||
|
||||
optionList.addAll(Arrays.asList("-classpath", classPathString));
|
||||
|
||||
//compile
|
||||
JavaCompiler.CompilationTask task = compiler.getTask(
|
||||
null, jfm, diagnostics, optionList, null,
|
||||
Arrays.asList(sourceCodeObject));
|
||||
|
||||
if (!task.call()) {
|
||||
throw new StrutsException("Compilation failed:" + diagnostics.getDiagnostics().get(0).toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected String getJarUrl(Class clazz) {
|
||||
ProtectionDomain protectionDomain = clazz.getProtectionDomain();
|
||||
CodeSource codeSource = protectionDomain.getCodeSource();
|
||||
URL loc = codeSource.getLocation();
|
||||
File file = FileUtils.toFile(loc);
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
private JspC compileJSP(String location) throws JasperException {
|
||||
JspC jspC = new JspC();
|
||||
jspC.setClassLoaderInterface(getClassLoaderInterface());
|
||||
jspC.setCompile(false);
|
||||
jspC.setJspFiles(location);
|
||||
jspC.setPackage(DEFAULT_PACKAGE);
|
||||
jspC.execute();
|
||||
return jspC;
|
||||
}
|
||||
|
||||
private ClassLoaderInterface getClassLoaderInterface() {
|
||||
ClassLoaderInterface classLoaderInterface = null;
|
||||
ServletContext ctx = ServletActionContext.getServletContext();
|
||||
if (ctx != null)
|
||||
classLoaderInterface = (ClassLoaderInterface) ctx.getAttribute(ClassLoaderInterface.CLASS_LOADER_INTERFACE);
|
||||
|
||||
return (ClassLoaderInterface) ObjectUtils.defaultIfNull(classLoaderInterface, new ClassLoaderInterfaceDelegate(JSPLoader.class.getClassLoader()));
|
||||
}
|
||||
|
||||
private static URI toURI(String name) {
|
||||
try {
|
||||
return new URI(name);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,79 +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.struts2;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
import org.apache.struts2.url.QueryStringParser;
|
||||
|
||||
import jakarta.servlet.Servlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.jsp.HttpJspPage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Maintains a cache of jsp locations -> servlet instances for those jsps. When a jsp is requested
|
||||
* from the cache, the cache will block if the jsp was not compiled already, and wait for the compilation
|
||||
*/
|
||||
public abstract class JSPRuntime {
|
||||
//maps from jsp path -> pagelet
|
||||
protected static final ServletCache servletCache = new ServletCache();
|
||||
|
||||
public static void clearCache() {
|
||||
servletCache.clear();
|
||||
}
|
||||
|
||||
public static void handle(String location) throws Exception {
|
||||
handle(location, false);
|
||||
}
|
||||
|
||||
public static void handle(String location, boolean flush) throws Exception {
|
||||
final HttpServletResponse response = ServletActionContext.getResponse();
|
||||
final HttpServletRequest request = ServletActionContext.getRequest();
|
||||
|
||||
int i = location.indexOf("?");
|
||||
if (i > 0) {
|
||||
//extract params from the url and add them to the request
|
||||
ActionContext actionContext = ServletActionContext.getActionContext();
|
||||
if (actionContext == null) {
|
||||
throw new StrutsException("Running out of action context!");
|
||||
}
|
||||
final QueryStringParser parser = actionContext.getInstance(QueryStringParser.class);
|
||||
String query = location.substring(i + 1);
|
||||
Map<String, Object> queryParams = parser.parse(query, true);
|
||||
if (queryParams != null && !queryParams.isEmpty()) {
|
||||
Map<String, Parameter> newParams = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
|
||||
newParams.put(entry.getKey(), new Parameter.Request(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
ActionContext.getContext().getParameters().appendAll(newParams);
|
||||
}
|
||||
location = location.substring(0, i);
|
||||
}
|
||||
|
||||
Servlet servlet = servletCache.get(location);
|
||||
HttpJspPage page = (HttpJspPage) servlet;
|
||||
|
||||
page._jspService(request, response);
|
||||
if (flush)
|
||||
response.flushBuffer();
|
||||
}
|
||||
}
|
||||
@@ -1,53 +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.struts2;
|
||||
|
||||
import jakarta.servlet.ServletConfig;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* Used to init the servlets for the jsps
|
||||
*/
|
||||
public class JSPServletConfig implements ServletConfig {
|
||||
private final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.EMPTY_LIST);
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
public JSPServletConfig(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
public String getInitParameter(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Enumeration getInitParameterNames() {
|
||||
return EMPTY_ENUMERATION;
|
||||
}
|
||||
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
|
||||
public String getServletName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +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.struts2;
|
||||
|
||||
import jakarta.servlet.Servlet;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* Caches servlet instances by jsp location. If a requested jsp is not in the cache, "get"
|
||||
* will block and wait for the jsp to be loaded
|
||||
*/
|
||||
public class ServletCache {
|
||||
protected final ConcurrentMap<String, Future<Servlet>> cache
|
||||
= new ConcurrentHashMap<String, Future<Servlet>>();
|
||||
|
||||
private final JSPLoader jspLoader = new JSPLoader();
|
||||
|
||||
public void clear() {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
public Servlet get(final String location) throws InterruptedException {
|
||||
while (true) {
|
||||
Future<Servlet> future = cache.get(location);
|
||||
if (future == null) {
|
||||
Callable<Servlet> loadJSPCallable = new Callable<Servlet>() {
|
||||
public Servlet call() throws Exception {
|
||||
return jspLoader.load(location);
|
||||
}
|
||||
};
|
||||
FutureTask<Servlet> futureTask = new FutureTask<Servlet>(loadJSPCallable);
|
||||
future = cache.putIfAbsent(location, futureTask);
|
||||
if (future == null) {
|
||||
future = futureTask;
|
||||
futureTask.run();
|
||||
}
|
||||
}
|
||||
try {
|
||||
return future.get();
|
||||
} catch (CancellationException e) {
|
||||
cache.remove(location, future);
|
||||
} catch (ExecutionException e) {
|
||||
throw launderThrowable(e.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static RuntimeException launderThrowable(Throwable t) {
|
||||
if (t instanceof RuntimeException)
|
||||
return (RuntimeException) t;
|
||||
else if (t instanceof Error)
|
||||
throw (Error) t;
|
||||
else
|
||||
throw new IllegalStateException(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +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.struts2.compiler;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Keeps a cache of class name -> MemoryJavaFileObject. If the requested class name is in the cache
|
||||
* a new class is defined for it, otherwise findClass delegates to the parent class loader
|
||||
*/
|
||||
public class MemoryClassLoader extends ClassLoader {
|
||||
private Map<String, MemoryJavaFileObject> cachedObjects = new ConcurrentHashMap<>();
|
||||
|
||||
public MemoryClassLoader() {
|
||||
//without this, the tests will not run, because the tests are loaded by a custom classloader
|
||||
//so the classes referenced from the compiled code will not be found by the System Class Loader because
|
||||
//the target dir is not part of the classpath used when calling the jvm to execute the tests
|
||||
super(Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws
|
||||
ClassNotFoundException {
|
||||
MemoryJavaFileObject fileObject = cachedObjects.get(name);
|
||||
if (fileObject != null) {
|
||||
byte[] bytes = fileObject.toByteArray();
|
||||
return defineClass(name, bytes, 0, bytes.length);
|
||||
}
|
||||
return super.findClass(name);
|
||||
}
|
||||
|
||||
public void addMemoryJavaFileObject(String jsp, MemoryJavaFileObject memoryJavaFileObject) {
|
||||
cachedObjects.put(jsp, memoryJavaFileObject);
|
||||
}
|
||||
}
|
||||
-59
@@ -1,59 +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.struts2.compiler;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* Captures the output of the java compiler in memory
|
||||
*/
|
||||
public class MemoryJavaFileObject extends SimpleJavaFileObject {
|
||||
|
||||
private ByteArrayOutputStream out;
|
||||
|
||||
public MemoryJavaFileObject(String name, JavaFileObject.Kind kind) {
|
||||
super(toURI(name), kind);
|
||||
}
|
||||
|
||||
public InputStream openInputStream() throws IOException,
|
||||
IllegalStateException, UnsupportedOperationException {
|
||||
return new ByteArrayInputStream(out.toByteArray());
|
||||
}
|
||||
|
||||
public OutputStream openOutputStream() throws IOException,
|
||||
IllegalStateException, UnsupportedOperationException {
|
||||
return out = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
private static URI toURI(String name) {
|
||||
try {
|
||||
return new URI(name);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return out.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -1,79 +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.struts2.el;
|
||||
|
||||
import jakarta.el.ELContext;
|
||||
import jakarta.el.ExpressionFactory;
|
||||
import jakarta.el.MethodExpression;
|
||||
import jakarta.el.ValueExpression;
|
||||
|
||||
import org.apache.struts2.el.lang.ELSupport;
|
||||
import org.apache.struts2.el.lang.ExpressionBuilder;
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
|
||||
/**
|
||||
* @see jakarta.el.ExpressionFactory
|
||||
*
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public class ExpressionFactoryImpl extends ExpressionFactory {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ExpressionFactoryImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Object coerceToType(Object obj, Class type) {
|
||||
return ELSupport.coerceToType(obj, type);
|
||||
}
|
||||
|
||||
public MethodExpression createMethodExpression(ELContext context,
|
||||
String expression, Class<?> expectedReturnType,
|
||||
Class<?>[] expectedParamTypes) {
|
||||
if (expectedParamTypes == null) {
|
||||
throw new NullPointerException(MessageFactory
|
||||
.get("error.method.nullParms"));
|
||||
}
|
||||
ExpressionBuilder builder = new ExpressionBuilder(expression, context);
|
||||
return builder.createMethodExpression(expectedReturnType,
|
||||
expectedParamTypes);
|
||||
}
|
||||
|
||||
public ValueExpression createValueExpression(ELContext context,
|
||||
String expression, Class expectedType) {
|
||||
if (expectedType == null) {
|
||||
throw new NullPointerException(MessageFactory
|
||||
.get("error.value.expectedType"));
|
||||
}
|
||||
ExpressionBuilder builder = new ExpressionBuilder(expression, context);
|
||||
return builder.createValueExpression(expectedType);
|
||||
}
|
||||
|
||||
public ValueExpression createValueExpression(Object instance,
|
||||
Class expectedType) {
|
||||
if (expectedType == null) {
|
||||
throw new NullPointerException(MessageFactory
|
||||
.get("error.value.expectedType"));
|
||||
}
|
||||
return new ValueExpressionLiteral(instance, expectedType);
|
||||
}
|
||||
}
|
||||
@@ -1,315 +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.struts2.el;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import jakarta.el.ELContext;
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.ELResolver;
|
||||
import jakarta.el.Expression;
|
||||
import jakarta.el.ExpressionFactory;
|
||||
import jakarta.el.FunctionMapper;
|
||||
import jakarta.el.MethodExpression;
|
||||
import jakarta.el.MethodInfo;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import jakarta.el.PropertyNotFoundException;
|
||||
import jakarta.el.VariableMapper;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
import org.apache.struts2.el.lang.ExpressionBuilder;
|
||||
import org.apache.struts2.el.parser.Node;
|
||||
import org.apache.struts2.el.util.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* An <code>Expression</code> that refers to a method on an object.
|
||||
*
|
||||
* <p>
|
||||
* The {@link ExpressionFactory#createMethodExpression} method
|
||||
* can be used to parse an expression string and return a concrete instance
|
||||
* of <code>MethodExpression</code> that encapsulates the parsed expression.
|
||||
* The {@link FunctionMapper} is used at parse time, not evaluation time,
|
||||
* so one is not needed to evaluate an expression using this class.
|
||||
* However, the {@link ELContext} is needed at evaluation time.</p>
|
||||
*
|
||||
* <p>The {@link #getMethodInfo} and {@link #invoke} methods will evaluate the
|
||||
* expression each time they are called. The {@link ELResolver} in the
|
||||
* <code>ELContext</code> is used to resolve the top-level variables and to
|
||||
* determine the behavior of the <code>.</code> and <code>[]</code>
|
||||
* operators. For any of the two methods, the {@link ELResolver#getValue}
|
||||
* method is used to resolve all properties up to but excluding the last
|
||||
* one. This provides the <code>base</code> object on which the method
|
||||
* appears. If the <code>base</code> object is null, a
|
||||
* <code>NullPointerException</code> must be thrown. At the last resolution,
|
||||
* the final <code>property</code> is then coerced to a <code>String</code>,
|
||||
* which provides the name of the method to be found. A method matching the
|
||||
* name and expected parameters provided at parse time is found and it is
|
||||
* either queried or invoked (depending on the method called on this
|
||||
* <code>MethodExpression</code>).</p>
|
||||
*
|
||||
* <p>See the notes about comparison, serialization and immutability in
|
||||
* the {@link Expression} javadocs.
|
||||
*
|
||||
* @see jakarta.el.ELResolver
|
||||
* @see jakarta.el.Expression
|
||||
* @see jakarta.el.ExpressionFactory
|
||||
* @see jakarta.el.MethodExpression
|
||||
*
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class MethodExpressionImpl extends MethodExpression implements
|
||||
Externalizable {
|
||||
|
||||
private Class expectedType;
|
||||
|
||||
private String expr;
|
||||
|
||||
private FunctionMapper fnMapper;
|
||||
|
||||
private VariableMapper varMapper;
|
||||
|
||||
private transient Node node;
|
||||
|
||||
private Class[] paramTypes;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public MethodExpressionImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expr expression
|
||||
* @param node node
|
||||
* @param fnMapper function mapper
|
||||
* @param varMapper variable mapper
|
||||
* @param expectedType expected type
|
||||
* @param paramTypes parameter types array
|
||||
*/
|
||||
public MethodExpressionImpl(String expr, Node node,
|
||||
FunctionMapper fnMapper, VariableMapper varMapper,
|
||||
Class expectedType, Class[] paramTypes) {
|
||||
super();
|
||||
this.expr = expr;
|
||||
this.node = node;
|
||||
this.fnMapper = fnMapper;
|
||||
this.varMapper = varMapper;
|
||||
this.expectedType = expectedType;
|
||||
this.paramTypes = paramTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the specified object is equal to this
|
||||
* <code>Expression</code>.
|
||||
*
|
||||
* <p>
|
||||
* The result is <code>true</code> if and only if the argument is not
|
||||
* <code>null</code>, is an <code>Expression</code> object that is the
|
||||
* of the same type (<code>ValueExpression</code> or
|
||||
* <code>MethodExpression</code>), and has an identical parsed
|
||||
* representation.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note that two expressions can be equal if their expression Strings are
|
||||
* different. For example, <code>${fn1:foo()}</code> and
|
||||
* <code>${fn2:foo()}</code> are equal if their corresponding
|
||||
* <code>FunctionMapper</code>s mapped <code>fn1:foo</code> and
|
||||
* <code>fn2:foo</code> to the same method.
|
||||
* </p>
|
||||
*
|
||||
* @param obj
|
||||
* the <code>Object</code> to test for equality.
|
||||
* @return <code>true</code> if <code>obj</code> equals this
|
||||
* <code>Expression</code>; <code>false</code> otherwise.
|
||||
* @see java.util.Hashtable
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof MethodExpressionImpl && obj.hashCode() == this
|
||||
.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the original String used to create this <code>Expression</code>,
|
||||
* unmodified.
|
||||
*
|
||||
* <p>
|
||||
* This is used for debugging purposes but also for the purposes of
|
||||
* comparison (e.g. to ensure the expression in a configuration file has not
|
||||
* changed).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This method does not provide sufficient information to re-create an
|
||||
* expression. Two different expressions can have exactly the same
|
||||
* expression string but different function mappings. Serialization should
|
||||
* be used to save and restore the state of an <code>Expression</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return The original expression String.
|
||||
*
|
||||
* @see jakarta.el.Expression#getExpressionString()
|
||||
*/
|
||||
public String getExpressionString() {
|
||||
return this.expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the expression relative to the provided context, and returns
|
||||
* information about the actual referenced method.
|
||||
*
|
||||
* @param context
|
||||
* The context of this evaluation
|
||||
* @return an instance of <code>MethodInfo</code> containing information
|
||||
* about the method the expression evaluated to.
|
||||
* @throws NullPointerException
|
||||
* if context is <code>null</code> or the base object is
|
||||
* <code>null</code> on the last resolution.
|
||||
* @throws PropertyNotFoundException
|
||||
* if one of the property resolutions failed because a specified
|
||||
* variable or property does not exist or is not readable.
|
||||
* @throws MethodNotFoundException
|
||||
* if no suitable method can be found.
|
||||
* @throws ELException
|
||||
* if an exception was thrown while performing property or
|
||||
* variable resolution. The thrown exception must be included as
|
||||
* the cause property of this exception, if available.
|
||||
* @see jakarta.el.MethodExpression#getMethodInfo(jakarta.el.ELContext)
|
||||
*/
|
||||
public MethodInfo getMethodInfo(ELContext context)
|
||||
throws PropertyNotFoundException, MethodNotFoundException,
|
||||
ELException {
|
||||
Node n = this.getNode();
|
||||
EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
|
||||
this.varMapper);
|
||||
return n.getMethodInfo(ctx, this.paramTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws ELException
|
||||
*/
|
||||
private Node getNode() throws ELException {
|
||||
if (this.node == null) {
|
||||
this.node = ExpressionBuilder.createNode(this.expr);
|
||||
}
|
||||
return this.node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code for this <code>Expression</code>.
|
||||
*
|
||||
* <p>
|
||||
* See the note in the {@link #equals} method on how two expressions can be
|
||||
* equal if their expression Strings are different. Recall that if two
|
||||
* objects are equal according to the <code>equals(Object)</code> method,
|
||||
* then calling the <code>hashCode</code> method on each of the two
|
||||
* objects must produce the same integer result. Implementations must take
|
||||
* special note and implement <code>hashCode</code> correctly.
|
||||
* </p>
|
||||
*
|
||||
* @return The hash code for this <code>Expression</code>.
|
||||
* @see #equals
|
||||
* @see java.util.Hashtable
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return this.expr.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the expression relative to the provided context, invokes the
|
||||
* method that was found using the supplied parameters, and returns the
|
||||
* result of the method invocation.
|
||||
*
|
||||
* @param context
|
||||
* The context of this evaluation.
|
||||
* @param params
|
||||
* The parameters to pass to the method, or <code>null</code>
|
||||
* if no parameters.
|
||||
* @return the result of the method invocation (<code>null</code> if the
|
||||
* method has a <code>void</code> return type).
|
||||
* @throws NullPointerException
|
||||
* if context is <code>null</code> or the base object is
|
||||
* <code>null</code> on the last resolution.
|
||||
* @throws PropertyNotFoundException
|
||||
* if one of the property resolutions failed because a specified
|
||||
* variable or property does not exist or is not readable.
|
||||
* @throws MethodNotFoundException
|
||||
* if no suitable method can be found.
|
||||
* @throws ELException
|
||||
* if an exception was thrown while performing property or
|
||||
* variable resolution. The thrown exception must be included as
|
||||
* the cause property of this exception, if available. If the
|
||||
* exception thrown is an <code>InvocationTargetException</code>,
|
||||
* extract its <code>cause</code> and pass it to the
|
||||
* <code>ELException</code> constructor.
|
||||
* @see jakarta.el.MethodExpression#invoke(jakarta.el.ELContext,
|
||||
* java.lang.Object[])
|
||||
*/
|
||||
public Object invoke(ELContext context, Object[] params)
|
||||
throws PropertyNotFoundException, MethodNotFoundException,
|
||||
ELException {
|
||||
EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
|
||||
this.varMapper);
|
||||
return this.getNode().invoke(ctx, this.paramTypes, params);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
this.expr = in.readUTF();
|
||||
String type = in.readUTF();
|
||||
if (!"".equals(type)) {
|
||||
this.expectedType = ReflectionUtil.forName(type);
|
||||
}
|
||||
this.paramTypes = ReflectionUtil.toTypeArray(((String[]) in
|
||||
.readObject()));
|
||||
this.fnMapper = (FunctionMapper) in.readObject();
|
||||
this.varMapper = (VariableMapper) in.readObject();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeUTF(this.expr);
|
||||
out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
|
||||
: "");
|
||||
out.writeObject(ReflectionUtil.toTypeNameArray(this.paramTypes));
|
||||
out.writeObject(this.fnMapper);
|
||||
out.writeObject(this.varMapper);
|
||||
}
|
||||
|
||||
public boolean isLiteralText() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,96 +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.struts2.el;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import jakarta.el.ELContext;
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.MethodExpression;
|
||||
import jakarta.el.MethodInfo;
|
||||
|
||||
import org.apache.struts2.el.lang.ELSupport;
|
||||
import org.apache.struts2.el.util.ReflectionUtil;
|
||||
|
||||
public class MethodExpressionLiteral extends MethodExpression implements Externalizable {
|
||||
|
||||
private Class expectedType;
|
||||
|
||||
private String expr;
|
||||
|
||||
private Class[] paramTypes;
|
||||
|
||||
public MethodExpressionLiteral() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public MethodExpressionLiteral(String expr, Class expectedType, Class[] paramTypes) {
|
||||
this.expr = expr;
|
||||
this.expectedType = expectedType;
|
||||
this.paramTypes = paramTypes;
|
||||
}
|
||||
|
||||
public MethodInfo getMethodInfo(ELContext context) throws ELException {
|
||||
return new MethodInfo(this.expr, this.expectedType, this.paramTypes);
|
||||
}
|
||||
|
||||
public Object invoke(ELContext context, Object[] params) throws ELException {
|
||||
if (this.expectedType != null) {
|
||||
return ELSupport.coerceToType(this.expr, this.expectedType);
|
||||
} else {
|
||||
return this.expr;
|
||||
}
|
||||
}
|
||||
|
||||
public String getExpressionString() {
|
||||
return this.expr;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof MethodExpressionLiteral && this.hashCode() == obj.hashCode());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.expr.hashCode();
|
||||
}
|
||||
|
||||
public boolean isLiteralText() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
this.expr = in.readUTF();
|
||||
String type = in.readUTF();
|
||||
if (!"".equals(type)) {
|
||||
this.expectedType = ReflectionUtil.forName(type);
|
||||
}
|
||||
this.paramTypes = ReflectionUtil.toTypeArray(((String[]) in
|
||||
.readObject()));
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeUTF(this.expr);
|
||||
out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
|
||||
: "");
|
||||
out.writeObject(ReflectionUtil.toTypeNameArray(this.paramTypes));
|
||||
}
|
||||
}
|
||||
@@ -1,267 +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.struts2.el;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import jakarta.el.ELContext;
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.ELResolver;
|
||||
import jakarta.el.Expression;
|
||||
import jakarta.el.ExpressionFactory;
|
||||
import jakarta.el.FunctionMapper;
|
||||
import jakarta.el.PropertyNotFoundException;
|
||||
import jakarta.el.PropertyNotWritableException;
|
||||
import jakarta.el.ValueExpression;
|
||||
import jakarta.el.VariableMapper;
|
||||
|
||||
import org.apache.struts2.el.lang.ELSupport;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
import org.apache.struts2.el.lang.ExpressionBuilder;
|
||||
import org.apache.struts2.el.parser.AstLiteralExpression;
|
||||
import org.apache.struts2.el.parser.Node;
|
||||
import org.apache.struts2.el.util.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* An <code>Expression</code> that can get or set a value.
|
||||
*
|
||||
* <p>
|
||||
* In previous incarnations of this API, expressions could only be read.
|
||||
* <code>ValueExpression</code> objects can now be used both to retrieve a
|
||||
* value and to set a value. Expressions that can have a value set on them are
|
||||
* referred to as l-value expressions. Those that cannot are referred to as
|
||||
* r-value expressions. Not all r-value expressions can be used as l-value
|
||||
* expressions (e.g. <code>"${1+1}"</code> or
|
||||
* <code>"${firstName} ${lastName}"</code>). See the EL Specification for
|
||||
* details. Expressions that cannot be used as l-values must always return
|
||||
* <code>true</code> from <code>isReadOnly()</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The {@link ExpressionFactory#createValueExpression} method
|
||||
* can be used to parse an expression string and return a concrete instance
|
||||
* of <code>ValueExpression</code> that encapsulates the parsed expression.
|
||||
* The {@link FunctionMapper} is used at parse time, not evaluation time,
|
||||
* so one is not needed to evaluate an expression using this class.
|
||||
* However, the {@link ELContext} is needed at evaluation time.</p>
|
||||
*
|
||||
* <p>The {@link #getValue}, {@link #setValue}, {@link #isReadOnly} and
|
||||
* {@link #getType} methods will evaluate the expression each time they are
|
||||
* called. The {@link ELResolver} in the <code>ELContext</code> is used to
|
||||
* resolve the top-level variables and to determine the behavior of the
|
||||
* <code>.</code> and <code>[]</code> operators. For any of the four methods,
|
||||
* the {@link ELResolver#getValue} method is used to resolve all properties
|
||||
* up to but excluding the last one. This provides the <code>base</code>
|
||||
* object. At the last resolution, the <code>ValueExpression</code> will
|
||||
* call the corresponding {@link ELResolver#getValue},
|
||||
* {@link ELResolver#setValue}, {@link ELResolver#isReadOnly} or
|
||||
* {@link ELResolver#getType} method, depending on which was called on
|
||||
* the <code>ValueExpression</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>See the notes about comparison, serialization and immutability in
|
||||
* the {@link Expression} javadocs.
|
||||
*
|
||||
* @see jakarta.el.ELResolver
|
||||
* @see jakarta.el.Expression
|
||||
* @see jakarta.el.ExpressionFactory
|
||||
* @see jakarta.el.ValueExpression
|
||||
*
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class ValueExpressionImpl extends ValueExpression implements
|
||||
Externalizable {
|
||||
|
||||
private Class expectedType;
|
||||
|
||||
private String expr;
|
||||
|
||||
private FunctionMapper fnMapper;
|
||||
|
||||
private VariableMapper varMapper;
|
||||
|
||||
private transient Node node;
|
||||
|
||||
public ValueExpressionImpl() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expr expression
|
||||
* @param node node
|
||||
* @param fnMapper function mapper
|
||||
* @param varMapper variable mapper
|
||||
* @param expectedType expected type
|
||||
*/
|
||||
public ValueExpressionImpl(String expr, Node node, FunctionMapper fnMapper,
|
||||
VariableMapper varMapper, Class expectedType) {
|
||||
this.expr = expr;
|
||||
this.node = node;
|
||||
this.fnMapper = fnMapper;
|
||||
this.varMapper = varMapper;
|
||||
this.expectedType = expectedType;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof ValueExpressionImpl && obj.hashCode() == this
|
||||
.hashCode());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see jakarta.el.ValueExpression#getExpectedType()
|
||||
*/
|
||||
public Class getExpectedType() {
|
||||
return this.expectedType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type the result of the expression will be coerced to after
|
||||
* evaluation.
|
||||
*
|
||||
* @return the <code>expectedType</code> passed to the
|
||||
* <code>ExpressionFactory.createValueExpression</code> method
|
||||
* that created this <code>ValueExpression</code>.
|
||||
*
|
||||
* @see jakarta.el.Expression#getExpressionString()
|
||||
*/
|
||||
public String getExpressionString() {
|
||||
return this.expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws ELException
|
||||
*/
|
||||
private Node getNode() throws ELException {
|
||||
if (this.node == null) {
|
||||
this.node = ExpressionBuilder.createNode(this.expr);
|
||||
}
|
||||
return this.node;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see jakarta.el.ValueExpression#getType(jakarta.el.ELContext)
|
||||
*/
|
||||
public Class getType(ELContext context) throws PropertyNotFoundException,
|
||||
ELException {
|
||||
EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
|
||||
this.varMapper);
|
||||
return this.getNode().getType(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see jakarta.el.ValueExpression#getValue(jakarta.el.ELContext)
|
||||
*/
|
||||
public Object getValue(ELContext context) throws PropertyNotFoundException,
|
||||
ELException {
|
||||
EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
|
||||
this.varMapper);
|
||||
Object value = this.getNode().getValue(ctx);
|
||||
if (this.expectedType != null) {
|
||||
return ELSupport.coerceToType(value, this.expectedType);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return this.expr.hashCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see jakarta.el.ValueExpression#isLiteralText()
|
||||
*/
|
||||
public boolean isLiteralText() {
|
||||
try {
|
||||
return this.getNode() instanceof AstLiteralExpression;
|
||||
} catch (ELException ele) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see jakarta.el.ValueExpression#isReadOnly(jakarta.el.ELContext)
|
||||
*/
|
||||
public boolean isReadOnly(ELContext context)
|
||||
throws PropertyNotFoundException, ELException {
|
||||
EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
|
||||
this.varMapper);
|
||||
return this.getNode().isReadOnly(ctx);
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
this.expr = in.readUTF();
|
||||
String type = in.readUTF();
|
||||
if (!"".equals(type)) {
|
||||
this.expectedType = ReflectionUtil.forName(type);
|
||||
}
|
||||
this.fnMapper = (FunctionMapper) in.readObject();
|
||||
this.varMapper = (VariableMapper) in.readObject();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see jakarta.el.ValueExpression#setValue(jakarta.el.ELContext,
|
||||
* java.lang.Object)
|
||||
*/
|
||||
public void setValue(ELContext context, Object value)
|
||||
throws PropertyNotFoundException, PropertyNotWritableException,
|
||||
ELException {
|
||||
EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
|
||||
this.varMapper);
|
||||
this.getNode().setValue(ctx, value);
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeUTF(this.expr);
|
||||
out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
|
||||
: "");
|
||||
out.writeObject(this.fnMapper);
|
||||
out.writeObject(this.varMapper);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ValueExpression["+this.expr+"]";
|
||||
}
|
||||
}
|
||||
@@ -1,113 +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.struts2.el;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import jakarta.el.ELContext;
|
||||
import jakarta.el.PropertyNotWritableException;
|
||||
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import jakarta.el.ValueExpression;
|
||||
|
||||
import org.apache.struts2.el.lang.ELSupport;
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
import org.apache.struts2.el.util.ReflectionUtil;
|
||||
|
||||
public final class ValueExpressionLiteral extends ValueExpression implements
|
||||
Externalizable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Object value;
|
||||
|
||||
private Class expectedType;
|
||||
|
||||
public ValueExpressionLiteral() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ValueExpressionLiteral(Object value, Class expectedType) {
|
||||
this.value = value;
|
||||
this.expectedType = expectedType;
|
||||
}
|
||||
|
||||
public Object getValue(ELContext context) {
|
||||
if (this.expectedType != null) {
|
||||
return ELSupport.coerceToType(this.value, this.expectedType);
|
||||
}
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(ELContext context, Object value) {
|
||||
throw new PropertyNotWritableException(MessageFactory.get(
|
||||
"error.value.literal.write", this.value));
|
||||
}
|
||||
|
||||
public boolean isReadOnly(ELContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Class getType(ELContext context) {
|
||||
return (this.value != null) ? this.value.getClass() : null;
|
||||
}
|
||||
|
||||
public Class getExpectedType() {
|
||||
return this.expectedType;
|
||||
}
|
||||
|
||||
public String getExpressionString() {
|
||||
return (this.value != null) ? this.value.toString() : null;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof ValueExpressionLiteral && this
|
||||
.equals((ValueExpressionLiteral) obj));
|
||||
}
|
||||
|
||||
public boolean equals(ValueExpressionLiteral ve) {
|
||||
return (ve != null && (this.value != null && ve.value != null && (this.value == ve.value || this.value
|
||||
.equals(ve.value))));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (this.value != null) ? this.value.hashCode() : 0;
|
||||
}
|
||||
|
||||
public boolean isLiteralText() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeObject(this.value);
|
||||
out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
|
||||
: "");
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
this.value = in.readObject();
|
||||
String type = in.readUTF();
|
||||
if (!"".equals(type)) {
|
||||
this.expectedType = ReflectionUtil.forName(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,378 +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.struts2.el.lang;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
|
||||
|
||||
/**
|
||||
* A helper class of Arithmetic defined by the EL Specification
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: rjung $
|
||||
*/
|
||||
public abstract class ELArithmetic {
|
||||
|
||||
public final static class BigDecimalDelegate extends ELArithmetic {
|
||||
|
||||
protected Number add(Number num0, Number num1) {
|
||||
return ((BigDecimal) num0).add((BigDecimal) num1);
|
||||
}
|
||||
|
||||
protected Number coerce(Number num) {
|
||||
if (num instanceof BigDecimal)
|
||||
return num;
|
||||
if (num instanceof BigInteger)
|
||||
return new BigDecimal((BigInteger) num);
|
||||
return new BigDecimal(num.doubleValue());
|
||||
}
|
||||
|
||||
protected Number coerce(String str) {
|
||||
return new BigDecimal(str);
|
||||
}
|
||||
|
||||
protected Number divide(Number num0, Number num1) {
|
||||
return ((BigDecimal) num0).divide((BigDecimal) num1,
|
||||
BigDecimal.ROUND_HALF_UP);
|
||||
}
|
||||
|
||||
protected Number subtract(Number num0, Number num1) {
|
||||
return ((BigDecimal) num0).subtract((BigDecimal) num1);
|
||||
}
|
||||
|
||||
protected Number mod(Number num0, Number num1) {
|
||||
return new Double(num0.doubleValue() % num1.doubleValue());
|
||||
}
|
||||
|
||||
protected Number multiply(Number num0, Number num1) {
|
||||
return ((BigDecimal) num0).multiply((BigDecimal) num1);
|
||||
}
|
||||
|
||||
public boolean matches(Object obj0, Object obj1) {
|
||||
return (obj0 instanceof BigDecimal || obj1 instanceof BigDecimal);
|
||||
}
|
||||
}
|
||||
|
||||
public final static class BigIntegerDelegate extends ELArithmetic {
|
||||
|
||||
protected Number add(Number num0, Number num1) {
|
||||
return ((BigInteger) num0).add((BigInteger) num1);
|
||||
}
|
||||
|
||||
protected Number coerce(Number num) {
|
||||
if (num instanceof BigInteger)
|
||||
return num;
|
||||
return new BigInteger(num.toString());
|
||||
}
|
||||
|
||||
protected Number coerce(String str) {
|
||||
return new BigInteger(str);
|
||||
}
|
||||
|
||||
protected Number divide(Number num0, Number num1) {
|
||||
return (new BigDecimal((BigInteger) num0)).divide(new BigDecimal((BigInteger) num1), BigDecimal.ROUND_HALF_UP);
|
||||
}
|
||||
|
||||
protected Number multiply(Number num0, Number num1) {
|
||||
return ((BigInteger) num0).multiply((BigInteger) num1);
|
||||
}
|
||||
|
||||
protected Number mod(Number num0, Number num1) {
|
||||
return ((BigInteger) num0).mod((BigInteger) num1);
|
||||
}
|
||||
|
||||
protected Number subtract(Number num0, Number num1) {
|
||||
return ((BigInteger) num0).subtract((BigInteger) num1);
|
||||
}
|
||||
|
||||
public boolean matches(Object obj0, Object obj1) {
|
||||
return (obj0 instanceof BigInteger || obj1 instanceof BigInteger);
|
||||
}
|
||||
}
|
||||
|
||||
public final static class DoubleDelegate extends ELArithmetic {
|
||||
|
||||
protected Number add(Number num0, Number num1) {
|
||||
// could only be one of these
|
||||
if (num0 instanceof BigDecimal) {
|
||||
return ((BigDecimal) num0).add(new BigDecimal(num1.doubleValue()));
|
||||
} else if (num1 instanceof BigDecimal) {
|
||||
return ((new BigDecimal(num0.doubleValue()).add((BigDecimal) num1)));
|
||||
}
|
||||
return new Double(num0.doubleValue() + num1.doubleValue());
|
||||
}
|
||||
|
||||
protected Number coerce(Number num) {
|
||||
if (num instanceof Double)
|
||||
return num;
|
||||
if (num instanceof BigInteger)
|
||||
return new BigDecimal((BigInteger) num);
|
||||
return new Double(num.doubleValue());
|
||||
}
|
||||
|
||||
protected Number coerce(String str) {
|
||||
return new Double(str);
|
||||
}
|
||||
|
||||
protected Number divide(Number num0, Number num1) {
|
||||
return new Double(num0.doubleValue() / num1.doubleValue());
|
||||
}
|
||||
|
||||
protected Number mod(Number num0, Number num1) {
|
||||
return new Double(num0.doubleValue() % num1.doubleValue());
|
||||
}
|
||||
|
||||
protected Number subtract(Number num0, Number num1) {
|
||||
// could only be one of these
|
||||
if (num0 instanceof BigDecimal) {
|
||||
return ((BigDecimal) num0).subtract(new BigDecimal(num1.doubleValue()));
|
||||
} else if (num1 instanceof BigDecimal) {
|
||||
return ((new BigDecimal(num0.doubleValue()).subtract((BigDecimal) num1)));
|
||||
}
|
||||
return new Double(num0.doubleValue() - num1.doubleValue());
|
||||
}
|
||||
|
||||
protected Number multiply(Number num0, Number num1) {
|
||||
// could only be one of these
|
||||
if (num0 instanceof BigDecimal) {
|
||||
return ((BigDecimal) num0).multiply(new BigDecimal(num1.doubleValue()));
|
||||
} else if (num1 instanceof BigDecimal) {
|
||||
return ((new BigDecimal(num0.doubleValue()).multiply((BigDecimal) num1)));
|
||||
}
|
||||
return new Double(num0.doubleValue() * num1.doubleValue());
|
||||
}
|
||||
|
||||
public boolean matches(Object obj0, Object obj1) {
|
||||
return (obj0 instanceof Double
|
||||
|| obj1 instanceof Double
|
||||
|| obj0 instanceof Float
|
||||
|| obj1 instanceof Float
|
||||
|| (obj0 instanceof String && ELSupport
|
||||
.isStringFloat((String) obj0)) || (obj1 instanceof String && ELSupport
|
||||
.isStringFloat((String) obj1)));
|
||||
}
|
||||
}
|
||||
|
||||
public final static class LongDelegate extends ELArithmetic {
|
||||
|
||||
protected Number add(Number num0, Number num1) {
|
||||
return new Long(num0.longValue() + num1.longValue());
|
||||
}
|
||||
|
||||
protected Number coerce(Number num) {
|
||||
if (num instanceof Long)
|
||||
return num;
|
||||
return new Long(num.longValue());
|
||||
}
|
||||
|
||||
protected Number coerce(String str) {
|
||||
return new Long(str);
|
||||
}
|
||||
|
||||
protected Number divide(Number num0, Number num1) {
|
||||
return new Long(num0.longValue() / num1.longValue());
|
||||
}
|
||||
|
||||
protected Number mod(Number num0, Number num1) {
|
||||
return new Long(num0.longValue() % num1.longValue());
|
||||
}
|
||||
|
||||
protected Number subtract(Number num0, Number num1) {
|
||||
return new Long(num0.longValue() - num1.longValue());
|
||||
}
|
||||
|
||||
protected Number multiply(Number num0, Number num1) {
|
||||
return new Long(num0.longValue() * num1.longValue());
|
||||
}
|
||||
|
||||
public boolean matches(Object obj0, Object obj1) {
|
||||
return (obj0 instanceof Long || obj1 instanceof Long);
|
||||
}
|
||||
}
|
||||
|
||||
public final static BigDecimalDelegate BIGDECIMAL = new BigDecimalDelegate();
|
||||
|
||||
public final static BigIntegerDelegate BIGINTEGER = new BigIntegerDelegate();
|
||||
|
||||
public final static DoubleDelegate DOUBLE = new DoubleDelegate();
|
||||
|
||||
public final static LongDelegate LONG = new LongDelegate();
|
||||
|
||||
private final static Long ZERO = new Long(0);
|
||||
|
||||
public final static Number add(final Object obj0, final Object obj1) {
|
||||
if (obj0 == null && obj1 == null) {
|
||||
return new Long(0);
|
||||
}
|
||||
|
||||
final ELArithmetic delegate;
|
||||
if (BIGDECIMAL.matches(obj0, obj1))
|
||||
delegate = BIGDECIMAL;
|
||||
else if (DOUBLE.matches(obj0, obj1))
|
||||
delegate = DOUBLE;
|
||||
else if (BIGINTEGER.matches(obj0, obj1))
|
||||
delegate = BIGINTEGER;
|
||||
else
|
||||
delegate = LONG;
|
||||
|
||||
Number num0 = delegate.coerce(obj0);
|
||||
Number num1 = delegate.coerce(obj1);
|
||||
|
||||
return delegate.add(num0, num1);
|
||||
}
|
||||
|
||||
public final static Number mod(final Object obj0, final Object obj1) {
|
||||
if (obj0 == null && obj1 == null) {
|
||||
return new Long(0);
|
||||
}
|
||||
|
||||
final ELArithmetic delegate;
|
||||
if (BIGDECIMAL.matches(obj0, obj1))
|
||||
delegate = BIGDECIMAL;
|
||||
else if (DOUBLE.matches(obj0, obj1))
|
||||
delegate = DOUBLE;
|
||||
else if (BIGINTEGER.matches(obj0, obj1))
|
||||
delegate = BIGINTEGER;
|
||||
else
|
||||
delegate = LONG;
|
||||
|
||||
Number num0 = delegate.coerce(obj0);
|
||||
Number num1 = delegate.coerce(obj1);
|
||||
|
||||
return delegate.mod(num0, num1);
|
||||
}
|
||||
|
||||
public final static Number subtract(final Object obj0, final Object obj1) {
|
||||
if (obj0 == null && obj1 == null) {
|
||||
return new Long(0);
|
||||
}
|
||||
|
||||
final ELArithmetic delegate;
|
||||
if (BIGDECIMAL.matches(obj0, obj1))
|
||||
delegate = BIGDECIMAL;
|
||||
else if (DOUBLE.matches(obj0, obj1))
|
||||
delegate = DOUBLE;
|
||||
else if (BIGINTEGER.matches(obj0, obj1))
|
||||
delegate = BIGINTEGER;
|
||||
else
|
||||
delegate = LONG;
|
||||
|
||||
Number num0 = delegate.coerce(obj0);
|
||||
Number num1 = delegate.coerce(obj1);
|
||||
|
||||
return delegate.subtract(num0, num1);
|
||||
}
|
||||
|
||||
public final static Number divide(final Object obj0, final Object obj1) {
|
||||
if (obj0 == null && obj1 == null) {
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
final ELArithmetic delegate;
|
||||
if (BIGDECIMAL.matches(obj0, obj1))
|
||||
delegate = BIGDECIMAL;
|
||||
else if (BIGINTEGER.matches(obj0, obj1))
|
||||
delegate = BIGDECIMAL;
|
||||
else
|
||||
delegate = DOUBLE;
|
||||
|
||||
Number num0 = delegate.coerce(obj0);
|
||||
Number num1 = delegate.coerce(obj1);
|
||||
|
||||
return delegate.divide(num0, num1);
|
||||
}
|
||||
|
||||
public final static Number multiply(final Object obj0, final Object obj1) {
|
||||
if (obj0 == null && obj1 == null) {
|
||||
return new Long(0);
|
||||
}
|
||||
|
||||
final ELArithmetic delegate;
|
||||
if (BIGDECIMAL.matches(obj0, obj1))
|
||||
delegate = BIGDECIMAL;
|
||||
else if (DOUBLE.matches(obj0, obj1))
|
||||
delegate = DOUBLE;
|
||||
else if (BIGINTEGER.matches(obj0, obj1))
|
||||
delegate = BIGINTEGER;
|
||||
else
|
||||
delegate = LONG;
|
||||
|
||||
Number num0 = delegate.coerce(obj0);
|
||||
Number num1 = delegate.coerce(obj1);
|
||||
|
||||
return delegate.multiply(num0, num1);
|
||||
}
|
||||
|
||||
public final static boolean isNumber(final Object obj) {
|
||||
return (obj != null && isNumberType(obj.getClass()));
|
||||
}
|
||||
|
||||
public final static boolean isNumberType(final Class<?> type) {
|
||||
return type == Long.TYPE || type == Double.TYPE ||
|
||||
type == Byte.TYPE || type == Short.TYPE ||
|
||||
type == Integer.TYPE || type == Float.TYPE ||
|
||||
Number.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected ELArithmetic() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected abstract Number add(final Number num0, final Number num1);
|
||||
|
||||
protected abstract Number multiply(final Number num0, final Number num1);
|
||||
|
||||
protected abstract Number subtract(final Number num0, final Number num1);
|
||||
|
||||
protected abstract Number mod(final Number num0, final Number num1);
|
||||
|
||||
protected abstract Number coerce(final Number num);
|
||||
|
||||
protected final Number coerce(final Object obj) {
|
||||
|
||||
if (isNumber(obj)) {
|
||||
return coerce((Number) obj);
|
||||
}
|
||||
if (obj instanceof String) {
|
||||
return coerce((String) obj);
|
||||
}
|
||||
if (obj == null || "".equals(obj)) {
|
||||
return coerce(ZERO);
|
||||
}
|
||||
|
||||
if (obj instanceof Character) {
|
||||
return coerce(new Short((short) ((Character) obj).charValue()));
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(MessageFactory.get("error.convert",
|
||||
obj, obj.getClass(), "Number"));
|
||||
}
|
||||
|
||||
protected abstract Number coerce(final String str);
|
||||
|
||||
protected abstract Number divide(final Number num0, final Number num1);
|
||||
|
||||
protected abstract boolean matches(final Object obj0, final Object obj1);
|
||||
|
||||
}
|
||||
@@ -1,474 +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.struts2.el.lang;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.beans.PropertyEditorManager;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.PropertyNotFoundException;
|
||||
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
|
||||
|
||||
/**
|
||||
* A helper class that implements the EL Specification
|
||||
*
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public class ELSupport {
|
||||
|
||||
private final static Long ZERO = new Long(0L);
|
||||
|
||||
public final static void throwUnhandled(Object base, Object property)
|
||||
throws ELException {
|
||||
if (base == null) {
|
||||
throw new PropertyNotFoundException(MessageFactory.get(
|
||||
"error.resolver.unhandled.null", property));
|
||||
} else {
|
||||
throw new PropertyNotFoundException(MessageFactory.get(
|
||||
"error.resolver.unhandled", base.getClass(), property));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj0 first object
|
||||
* @param obj1 second object
|
||||
* @return 0 if objects are equals
|
||||
* @throws ELException in case of errors
|
||||
*/
|
||||
public final static int compare(final Object obj0, final Object obj1)
|
||||
throws ELException {
|
||||
if (obj0 == obj1 || equals(obj0, obj1)) {
|
||||
return 0;
|
||||
}
|
||||
if (isBigDecimalOp(obj0, obj1)) {
|
||||
BigDecimal bd0 = (BigDecimal) coerceToNumber(obj0, BigDecimal.class);
|
||||
BigDecimal bd1 = (BigDecimal) coerceToNumber(obj1, BigDecimal.class);
|
||||
return bd0.compareTo(bd1);
|
||||
}
|
||||
if (isDoubleOp(obj0, obj1)) {
|
||||
Double d0 = (Double) coerceToNumber(obj0, Double.class);
|
||||
Double d1 = (Double) coerceToNumber(obj1, Double.class);
|
||||
return d0.compareTo(d1);
|
||||
}
|
||||
if (isBigIntegerOp(obj0, obj1)) {
|
||||
BigInteger bi0 = (BigInteger) coerceToNumber(obj0, BigInteger.class);
|
||||
BigInteger bi1 = (BigInteger) coerceToNumber(obj1, BigInteger.class);
|
||||
return bi0.compareTo(bi1);
|
||||
}
|
||||
if (isLongOp(obj0, obj1)) {
|
||||
Long l0 = (Long) coerceToNumber(obj0, Long.class);
|
||||
Long l1 = (Long) coerceToNumber(obj1, Long.class);
|
||||
return l0.compareTo(l1);
|
||||
}
|
||||
if (obj0 instanceof String || obj1 instanceof String) {
|
||||
return coerceToString(obj0).compareTo(coerceToString(obj1));
|
||||
}
|
||||
if (obj0 instanceof Comparable) {
|
||||
return (obj1 != null) ? ((Comparable) obj0).compareTo(obj1) : 1;
|
||||
}
|
||||
if (obj1 instanceof Comparable) {
|
||||
return (obj0 != null) ? -((Comparable) obj1).compareTo(obj0) : -1;
|
||||
}
|
||||
throw new ELException(MessageFactory.get("error.compare", obj0, obj1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj0 first object
|
||||
* @param obj1 second object
|
||||
* @return true if objects are equals
|
||||
* @throws ELException in case of errors
|
||||
*/
|
||||
public final static boolean equals(final Object obj0, final Object obj1)
|
||||
throws ELException {
|
||||
if (obj0 == obj1) {
|
||||
return true;
|
||||
} else if (obj0 == null || obj1 == null) {
|
||||
return false;
|
||||
} else if (obj0 instanceof Boolean || obj1 instanceof Boolean) {
|
||||
return coerceToBoolean(obj0).equals(coerceToBoolean(obj1));
|
||||
} else if (obj0.getClass().isEnum()) {
|
||||
return obj0.equals(coerceToEnum(obj1, obj0.getClass()));
|
||||
} else if (obj1.getClass().isEnum()) {
|
||||
return obj1.equals(coerceToEnum(obj0, obj1.getClass()));
|
||||
} else if (obj0 instanceof String || obj1 instanceof String) {
|
||||
int lexCompare = coerceToString(obj0).compareTo(coerceToString(obj1));
|
||||
return (lexCompare == 0) ? true : false;
|
||||
}
|
||||
if (isBigDecimalOp(obj0, obj1)) {
|
||||
BigDecimal bd0 = (BigDecimal) coerceToNumber(obj0, BigDecimal.class);
|
||||
BigDecimal bd1 = (BigDecimal) coerceToNumber(obj1, BigDecimal.class);
|
||||
return bd0.equals(bd1);
|
||||
}
|
||||
if (isDoubleOp(obj0, obj1)) {
|
||||
Double d0 = (Double) coerceToNumber(obj0, Double.class);
|
||||
Double d1 = (Double) coerceToNumber(obj1, Double.class);
|
||||
return d0.equals(d1);
|
||||
}
|
||||
if (isBigIntegerOp(obj0, obj1)) {
|
||||
BigInteger bi0 = (BigInteger) coerceToNumber(obj0, BigInteger.class);
|
||||
BigInteger bi1 = (BigInteger) coerceToNumber(obj1, BigInteger.class);
|
||||
return bi0.equals(bi1);
|
||||
}
|
||||
if (isLongOp(obj0, obj1)) {
|
||||
Long l0 = (Long) coerceToNumber(obj0, Long.class);
|
||||
Long l1 = (Long) coerceToNumber(obj1, Long.class);
|
||||
return l0.equals(l1);
|
||||
} else {
|
||||
return obj0.equals(obj1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj object
|
||||
* @param type class ytpe
|
||||
* @return enum
|
||||
*/
|
||||
public final static Enum coerceToEnum(final Object obj, Class type) {
|
||||
if (obj == null || "".equals(obj)) {
|
||||
return null;
|
||||
}
|
||||
if (obj.getClass().isEnum()) {
|
||||
return (Enum) obj;
|
||||
}
|
||||
return Enum.valueOf(type, obj.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj object
|
||||
* @return boolean
|
||||
*/
|
||||
public final static Boolean coerceToBoolean(final Object obj)
|
||||
throws IllegalArgumentException {
|
||||
if (obj == null || "".equals(obj)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
if (obj instanceof Boolean) {
|
||||
return (Boolean) obj;
|
||||
}
|
||||
if (obj instanceof String) {
|
||||
return Boolean.valueOf((String) obj);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(MessageFactory.get("error.convert",
|
||||
obj, obj.getClass(), Boolean.class));
|
||||
}
|
||||
|
||||
public final static Character coerceToCharacter(final Object obj)
|
||||
throws IllegalArgumentException {
|
||||
if (obj == null || "".equals(obj)) {
|
||||
return new Character((char) 0);
|
||||
}
|
||||
if (obj instanceof String) {
|
||||
return new Character(((String) obj).charAt(0));
|
||||
}
|
||||
if (ELArithmetic.isNumber(obj)) {
|
||||
return new Character((char) ((Number) obj).shortValue());
|
||||
}
|
||||
Class objType = obj.getClass();
|
||||
if (obj instanceof Character) {
|
||||
return (Character) obj;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(MessageFactory.get("error.convert",
|
||||
obj, objType, Character.class));
|
||||
}
|
||||
|
||||
public final static Number coerceToNumber(final Object obj) {
|
||||
if (obj == null) {
|
||||
return ZERO;
|
||||
} else if (obj instanceof Number) {
|
||||
return (Number) obj;
|
||||
} else {
|
||||
String str = coerceToString(obj);
|
||||
if (isStringFloat(str)) {
|
||||
return toFloat(str);
|
||||
} else {
|
||||
return toNumber(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected final static Number coerceToNumber(final Number number,
|
||||
final Class type) throws IllegalArgumentException {
|
||||
if (Long.TYPE == type || Long.class.equals(type)) {
|
||||
return new Long(number.longValue());
|
||||
}
|
||||
if (Double.TYPE == type || Double.class.equals(type)) {
|
||||
return new Double(number.doubleValue());
|
||||
}
|
||||
if (Integer.TYPE == type || Integer.class.equals(type)) {
|
||||
return new Integer(number.intValue());
|
||||
}
|
||||
if (BigInteger.class.equals(type)) {
|
||||
if (number instanceof BigDecimal) {
|
||||
return ((BigDecimal) number).toBigInteger();
|
||||
}
|
||||
if (number instanceof BigInteger) {
|
||||
return number;
|
||||
}
|
||||
return BigInteger.valueOf(number.longValue());
|
||||
}
|
||||
if (BigDecimal.class.equals(type)) {
|
||||
if (number instanceof BigDecimal) {
|
||||
return number;
|
||||
}
|
||||
if (number instanceof BigInteger) {
|
||||
return new BigDecimal((BigInteger) number);
|
||||
}
|
||||
return new BigDecimal(number.doubleValue());
|
||||
}
|
||||
if (Byte.TYPE == type || Byte.class.equals(type)) {
|
||||
return new Byte(number.byteValue());
|
||||
}
|
||||
if (Short.TYPE == type || Short.class.equals(type)) {
|
||||
return new Short(number.shortValue());
|
||||
}
|
||||
if (Float.TYPE == type || Float.class.equals(type)) {
|
||||
return new Float(number.floatValue());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(MessageFactory.get("error.convert",
|
||||
number, number.getClass(), type));
|
||||
}
|
||||
|
||||
public final static Number coerceToNumber(final Object obj, final Class type)
|
||||
throws IllegalArgumentException {
|
||||
if (obj == null || "".equals(obj)) {
|
||||
return coerceToNumber(ZERO, type);
|
||||
}
|
||||
if (obj instanceof String) {
|
||||
return coerceToNumber((String) obj, type);
|
||||
}
|
||||
if (ELArithmetic.isNumber(obj)) {
|
||||
return coerceToNumber((Number) obj, type);
|
||||
}
|
||||
|
||||
if (obj instanceof Character) {
|
||||
return coerceToNumber(new Short((short) ((Character) obj)
|
||||
.charValue()), type);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(MessageFactory.get("error.convert",
|
||||
obj, obj.getClass(), type));
|
||||
}
|
||||
|
||||
protected final static Number coerceToNumber(final String val,
|
||||
final Class type) throws IllegalArgumentException {
|
||||
if (Long.TYPE == type || Long.class.equals(type)) {
|
||||
return Long.valueOf(val);
|
||||
}
|
||||
if (Integer.TYPE == type || Integer.class.equals(type)) {
|
||||
return Integer.valueOf(val);
|
||||
}
|
||||
if (Double.TYPE == type || Double.class.equals(type)) {
|
||||
return Double.valueOf(val);
|
||||
}
|
||||
if (BigInteger.class.equals(type)) {
|
||||
return new BigInteger(val);
|
||||
}
|
||||
if (BigDecimal.class.equals(type)) {
|
||||
return new BigDecimal(val);
|
||||
}
|
||||
if (Byte.TYPE == type || Byte.class.equals(type)) {
|
||||
return Byte.valueOf(val);
|
||||
}
|
||||
if (Short.TYPE == type || Short.class.equals(type)) {
|
||||
return Short.valueOf(val);
|
||||
}
|
||||
if (Float.TYPE == type || Float.class.equals(type)) {
|
||||
return Float.valueOf(val);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(MessageFactory.get("error.convert",
|
||||
val, String.class, type));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj object
|
||||
* @return String
|
||||
*/
|
||||
public final static String coerceToString(final Object obj) {
|
||||
if (obj == null) {
|
||||
return "";
|
||||
} else if (obj instanceof String) {
|
||||
return (String) obj;
|
||||
} else if (obj instanceof Enum) {
|
||||
return ((Enum) obj).name();
|
||||
} else {
|
||||
return obj.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public final static void checkType(final Object obj, final Class type)
|
||||
throws IllegalArgumentException {
|
||||
if (String.class.equals(type)) {
|
||||
coerceToString(obj);
|
||||
}
|
||||
if (ELArithmetic.isNumberType(type)) {
|
||||
coerceToNumber(obj, type);
|
||||
}
|
||||
if (Character.class.equals(type) || Character.TYPE == type) {
|
||||
coerceToCharacter(obj);
|
||||
}
|
||||
if (Boolean.class.equals(type) || Boolean.TYPE == type) {
|
||||
coerceToBoolean(obj);
|
||||
}
|
||||
if (type.isEnum()) {
|
||||
coerceToEnum(obj, type);
|
||||
}
|
||||
}
|
||||
|
||||
public final static Object coerceToType(final Object obj, final Class type)
|
||||
throws IllegalArgumentException {
|
||||
if (type == null || Object.class.equals(type) ||
|
||||
(obj != null && type.isAssignableFrom(obj.getClass()))) {
|
||||
return obj;
|
||||
}
|
||||
if (String.class.equals(type)) {
|
||||
return coerceToString(obj);
|
||||
}
|
||||
if (ELArithmetic.isNumberType(type)) {
|
||||
return coerceToNumber(obj, type);
|
||||
}
|
||||
if (Character.class.equals(type) || Character.TYPE == type) {
|
||||
return coerceToCharacter(obj);
|
||||
}
|
||||
if (Boolean.class.equals(type) || Boolean.TYPE == type) {
|
||||
return coerceToBoolean(obj);
|
||||
}
|
||||
if (type.isEnum()) {
|
||||
return coerceToEnum(obj, type);
|
||||
}
|
||||
|
||||
// new to spec
|
||||
if (obj == null)
|
||||
return null;
|
||||
if (obj instanceof String) {
|
||||
if ("".equals(obj))
|
||||
return null;
|
||||
PropertyEditor editor = PropertyEditorManager.findEditor(type);
|
||||
if (editor != null) {
|
||||
editor.setAsText((String) obj);
|
||||
return editor.getValue();
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(MessageFactory.get("error.convert",
|
||||
obj, obj.getClass(), type));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj object array
|
||||
* @return true if object array contains null values
|
||||
*/
|
||||
public final static boolean containsNulls(final Object[] obj) {
|
||||
for (int i = 0; i < obj.length; i++) {
|
||||
if (obj[i] == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final static boolean isBigDecimalOp(final Object obj0,
|
||||
final Object obj1) {
|
||||
return (obj0 instanceof BigDecimal || obj1 instanceof BigDecimal);
|
||||
}
|
||||
|
||||
public final static boolean isBigIntegerOp(final Object obj0,
|
||||
final Object obj1) {
|
||||
return (obj0 instanceof BigInteger || obj1 instanceof BigInteger);
|
||||
}
|
||||
|
||||
public final static boolean isDoubleOp(final Object obj0, final Object obj1) {
|
||||
return (obj0 instanceof Double
|
||||
|| obj1 instanceof Double
|
||||
|| obj0 instanceof Float
|
||||
|| obj1 instanceof Float);
|
||||
}
|
||||
|
||||
public final static boolean isDoubleStringOp(final Object obj0,
|
||||
final Object obj1) {
|
||||
return (isDoubleOp(obj0, obj1)
|
||||
|| (obj0 instanceof String && isStringFloat((String) obj0)) || (obj1 instanceof String && isStringFloat((String) obj1)));
|
||||
}
|
||||
|
||||
public final static boolean isLongOp(final Object obj0, final Object obj1) {
|
||||
return (obj0 instanceof Long
|
||||
|| obj1 instanceof Long
|
||||
|| obj0 instanceof Integer
|
||||
|| obj1 instanceof Integer
|
||||
|| obj0 instanceof Character
|
||||
|| obj1 instanceof Character
|
||||
|| obj0 instanceof Short
|
||||
|| obj1 instanceof Short
|
||||
|| obj0 instanceof Byte
|
||||
|| obj1 instanceof Byte);
|
||||
}
|
||||
|
||||
public final static boolean isStringFloat(final String str) {
|
||||
int len = str.length();
|
||||
if (len > 1) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch (str.charAt(i)) {
|
||||
case 'E':
|
||||
return true;
|
||||
case 'e':
|
||||
return true;
|
||||
case '.':
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final static Number toFloat(final String value) {
|
||||
try {
|
||||
if (Double.parseDouble(value) > Double.MAX_VALUE) {
|
||||
return new BigDecimal(value);
|
||||
} else {
|
||||
return new Double(value);
|
||||
}
|
||||
} catch (NumberFormatException e0) {
|
||||
return new BigDecimal(value);
|
||||
}
|
||||
}
|
||||
|
||||
public final static Number toNumber(final String value) {
|
||||
try {
|
||||
return new Integer(Integer.parseInt(value));
|
||||
} catch (NumberFormatException e0) {
|
||||
try {
|
||||
return new Long(Long.parseLong(value));
|
||||
} catch (NumberFormatException e1) {
|
||||
return new BigInteger(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ELSupport() {
|
||||
super();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +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.struts2.el.lang;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import jakarta.el.ELContext;
|
||||
import jakarta.el.ELResolver;
|
||||
import jakarta.el.FunctionMapper;
|
||||
import jakarta.el.VariableMapper;
|
||||
|
||||
public final class EvaluationContext extends ELContext {
|
||||
|
||||
private final ELContext elContext;
|
||||
|
||||
private final FunctionMapper fnMapper;
|
||||
|
||||
private final VariableMapper varMapper;
|
||||
|
||||
public EvaluationContext(ELContext elContext, FunctionMapper fnMapper,
|
||||
VariableMapper varMapper) {
|
||||
this.elContext = elContext;
|
||||
this.fnMapper = fnMapper;
|
||||
this.varMapper = varMapper;
|
||||
}
|
||||
|
||||
public ELContext getELContext() {
|
||||
return this.elContext;
|
||||
}
|
||||
|
||||
public FunctionMapper getFunctionMapper() {
|
||||
return this.fnMapper;
|
||||
}
|
||||
|
||||
public VariableMapper getVariableMapper() {
|
||||
return this.varMapper;
|
||||
}
|
||||
|
||||
public Object getContext(Class key) {
|
||||
return this.elContext.getContext(key);
|
||||
}
|
||||
|
||||
public ELResolver getELResolver() {
|
||||
return this.elContext.getELResolver();
|
||||
}
|
||||
|
||||
public boolean isPropertyResolved() {
|
||||
return this.elContext.isPropertyResolved();
|
||||
}
|
||||
|
||||
public void putContext(Class key, Object contextObject) {
|
||||
this.elContext.putContext(key, contextObject);
|
||||
}
|
||||
|
||||
public void setPropertyResolved(boolean resolved) {
|
||||
this.elContext.setPropertyResolved(resolved);
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return this.elContext.getLocale();
|
||||
}
|
||||
|
||||
public void setLocale(Locale locale) {
|
||||
this.elContext.setLocale(locale);
|
||||
}
|
||||
}
|
||||
@@ -1,211 +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.struts2.el.lang;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import jakarta.el.ELContext;
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.FunctionMapper;
|
||||
import jakarta.el.MethodExpression;
|
||||
import jakarta.el.ValueExpression;
|
||||
import jakarta.el.VariableMapper;
|
||||
|
||||
import org.apache.struts2.el.MethodExpressionImpl;
|
||||
import org.apache.struts2.el.MethodExpressionLiteral;
|
||||
import org.apache.struts2.el.ValueExpressionImpl;
|
||||
import org.apache.struts2.el.parser.AstCompositeExpression;
|
||||
import org.apache.struts2.el.parser.AstDeferredExpression;
|
||||
import org.apache.struts2.el.parser.AstDynamicExpression;
|
||||
import org.apache.struts2.el.parser.AstFunction;
|
||||
import org.apache.struts2.el.parser.AstIdentifier;
|
||||
import org.apache.struts2.el.parser.AstLiteralExpression;
|
||||
import org.apache.struts2.el.parser.AstValue;
|
||||
import org.apache.struts2.el.parser.ELParser;
|
||||
import org.apache.struts2.el.parser.Node;
|
||||
import org.apache.struts2.el.parser.NodeVisitor;
|
||||
import org.apache.struts2.el.parser.ParseException;
|
||||
import org.apache.struts2.el.util.ConcurrentCache;
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: rjung $
|
||||
*/
|
||||
public final class ExpressionBuilder implements NodeVisitor {
|
||||
|
||||
private static final ConcurrentCache<String, Node> cache = new ConcurrentCache<String, Node>(5000);
|
||||
|
||||
private FunctionMapper fnMapper;
|
||||
|
||||
private VariableMapper varMapper;
|
||||
|
||||
private String expression;
|
||||
|
||||
public ExpressionBuilder(String expression, ELContext ctx)
|
||||
throws ELException {
|
||||
this.expression = expression;
|
||||
|
||||
FunctionMapper ctxFn = ctx.getFunctionMapper();
|
||||
VariableMapper ctxVar = ctx.getVariableMapper();
|
||||
|
||||
if (ctxFn != null) {
|
||||
this.fnMapper = new FunctionMapperFactory(ctxFn);
|
||||
}
|
||||
if (ctxVar != null) {
|
||||
this.varMapper = new VariableMapperFactory(ctxVar);
|
||||
}
|
||||
}
|
||||
|
||||
public final static Node createNode(String expr) throws ELException {
|
||||
Node n = createNodeInternal(expr);
|
||||
return n;
|
||||
}
|
||||
|
||||
private final static Node createNodeInternal(String expr)
|
||||
throws ELException {
|
||||
if (expr == null) {
|
||||
throw new ELException(MessageFactory.get("error.null"));
|
||||
}
|
||||
|
||||
Node n = cache.get(expr);
|
||||
if (n == null) {
|
||||
try {
|
||||
n = (new ELParser(new StringReader(expr)))
|
||||
.CompositeExpression();
|
||||
|
||||
// validate composite expression
|
||||
if (n instanceof AstCompositeExpression) {
|
||||
int numChildren = n.jjtGetNumChildren();
|
||||
if (numChildren == 1) {
|
||||
n = n.jjtGetChild(0);
|
||||
} else {
|
||||
Class type = null;
|
||||
Node child = null;
|
||||
for (int i = 0; i < numChildren; i++) {
|
||||
child = n.jjtGetChild(i);
|
||||
if (child instanceof AstLiteralExpression)
|
||||
continue;
|
||||
if (type == null)
|
||||
type = child.getClass();
|
||||
else {
|
||||
if (!type.equals(child.getClass())) {
|
||||
throw new ELException(MessageFactory.get(
|
||||
"error.mixed", expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n instanceof AstDeferredExpression
|
||||
|| n instanceof AstDynamicExpression) {
|
||||
n = n.jjtGetChild(0);
|
||||
}
|
||||
cache.put(expr, n);
|
||||
} catch (ParseException pe) {
|
||||
throw new ELException("Error Parsing: " + expr, pe);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private void prepare(Node node) throws ELException {
|
||||
try {
|
||||
node.accept(this);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ELException) {
|
||||
throw (ELException) e;
|
||||
} else {
|
||||
throw (new ELException(e));
|
||||
}
|
||||
}
|
||||
if (this.fnMapper instanceof FunctionMapperFactory) {
|
||||
this.fnMapper = ((FunctionMapperFactory) this.fnMapper).create();
|
||||
}
|
||||
if (this.varMapper instanceof VariableMapperFactory) {
|
||||
this.varMapper = ((VariableMapperFactory) this.varMapper).create();
|
||||
}
|
||||
}
|
||||
|
||||
private Node build() throws ELException {
|
||||
Node n = createNodeInternal(this.expression);
|
||||
this.prepare(n);
|
||||
if (n instanceof AstDeferredExpression
|
||||
|| n instanceof AstDynamicExpression) {
|
||||
n = n.jjtGetChild(0);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.sun.el.parser.NodeVisitor#visit(com.sun.el.parser.Node)
|
||||
*/
|
||||
public void visit(Node node) throws ELException {
|
||||
if (node instanceof AstFunction) {
|
||||
|
||||
AstFunction funcNode = (AstFunction) node;
|
||||
|
||||
if (this.fnMapper == null) {
|
||||
throw new ELException(MessageFactory.get("error.fnMapper.null"));
|
||||
}
|
||||
Method m = fnMapper.resolveFunction(funcNode.getPrefix(), funcNode
|
||||
.getLocalName());
|
||||
if (m == null) {
|
||||
throw new ELException(MessageFactory.get(
|
||||
"error.fnMapper.method", funcNode.getOutputName()));
|
||||
}
|
||||
int pcnt = m.getParameterTypes().length;
|
||||
if (node.jjtGetNumChildren() != pcnt) {
|
||||
throw new ELException(MessageFactory.get(
|
||||
"error.fnMapper.paramcount", funcNode.getOutputName(),
|
||||
"" + pcnt, "" + node.jjtGetNumChildren()));
|
||||
}
|
||||
} else if (node instanceof AstIdentifier && this.varMapper != null) {
|
||||
String variable = ((AstIdentifier) node).getImage();
|
||||
|
||||
// simply capture it
|
||||
this.varMapper.resolveVariable(variable);
|
||||
}
|
||||
}
|
||||
|
||||
public ValueExpression createValueExpression(Class expectedType)
|
||||
throws ELException {
|
||||
Node n = this.build();
|
||||
return new ValueExpressionImpl(this.expression, n, this.fnMapper,
|
||||
this.varMapper, expectedType);
|
||||
}
|
||||
|
||||
public MethodExpression createMethodExpression(Class expectedReturnType,
|
||||
Class[] expectedParamTypes) throws ELException {
|
||||
Node n = this.build();
|
||||
if (n instanceof AstValue || n instanceof AstIdentifier) {
|
||||
return new MethodExpressionImpl(expression, n, this.fnMapper,
|
||||
this.varMapper, expectedReturnType, expectedParamTypes);
|
||||
} else if (n instanceof AstLiteralExpression) {
|
||||
return new MethodExpressionLiteral(expression, expectedReturnType,
|
||||
expectedParamTypes);
|
||||
} else {
|
||||
throw new ELException("Not a Valid Method Expression: "
|
||||
+ expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
-60
@@ -1,60 +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.struts2.el.lang;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import jakarta.el.FunctionMapper;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: rjung $
|
||||
*/
|
||||
public class FunctionMapperFactory extends FunctionMapper {
|
||||
|
||||
protected FunctionMapperImpl memento = null;
|
||||
protected FunctionMapper target;
|
||||
|
||||
public FunctionMapperFactory(FunctionMapper mapper) {
|
||||
if (mapper == null) {
|
||||
throw new NullPointerException("FunctionMapper target cannot be null");
|
||||
}
|
||||
this.target = mapper;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see jakarta.el.FunctionMapper#resolveFunction(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public Method resolveFunction(String prefix, String localName) {
|
||||
if (this.memento == null) {
|
||||
this.memento = new FunctionMapperImpl();
|
||||
}
|
||||
Method m = this.target.resolveFunction(prefix, localName);
|
||||
if (m != null) {
|
||||
this.memento.addFunction(prefix, localName, m);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
public FunctionMapper create() {
|
||||
return this.memento;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,190 +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.struts2.el.lang;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.el.FunctionMapper;
|
||||
|
||||
import org.apache.struts2.el.util.ReflectionUtil;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: rjung $
|
||||
*/
|
||||
public class FunctionMapperImpl extends FunctionMapper implements
|
||||
Externalizable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected Map<String, Function> functions = null;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see jakarta.el.FunctionMapper#resolveFunction(java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Method resolveFunction(String prefix, String localName) {
|
||||
if (this.functions != null) {
|
||||
Function f = this.functions.get(prefix + ":" + localName);
|
||||
return f.getMethod();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addFunction(String prefix, String localName, Method m) {
|
||||
if (this.functions == null) {
|
||||
this.functions = new HashMap<String, Function>();
|
||||
}
|
||||
Function f = new Function(prefix, localName, m);
|
||||
synchronized (this) {
|
||||
this.functions.put(prefix+":"+localName, f);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeObject(this.functions);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
this.functions = (Map<String, Function>) in.readObject();
|
||||
}
|
||||
|
||||
public static class Function implements Externalizable {
|
||||
|
||||
protected transient Method m;
|
||||
protected String owner;
|
||||
protected String name;
|
||||
protected String[] types;
|
||||
protected String prefix;
|
||||
protected String localName;
|
||||
|
||||
public Function(String prefix, String localName, Method m) {
|
||||
if (localName == null) {
|
||||
throw new NullPointerException("LocalName cannot be null");
|
||||
}
|
||||
if (m == null) {
|
||||
throw new NullPointerException("Method cannot be null");
|
||||
}
|
||||
this.prefix = prefix;
|
||||
this.localName = localName;
|
||||
this.m = m;
|
||||
}
|
||||
|
||||
public Function() {
|
||||
// for serialization
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeUTF((this.prefix != null) ? this.prefix : "");
|
||||
out.writeUTF(this.localName);
|
||||
// make sure m isn't null
|
||||
getMethod();
|
||||
out.writeUTF((this.owner != null) ?
|
||||
this.owner :
|
||||
this.m.getDeclaringClass().getName());
|
||||
out.writeUTF((this.name != null) ?
|
||||
this.name :
|
||||
this.m.getName());
|
||||
out.writeObject((this.types != null) ?
|
||||
this.types :
|
||||
ReflectionUtil.toTypeNameArray(this.m.getParameterTypes()));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
|
||||
this.prefix = in.readUTF();
|
||||
if ("".equals(this.prefix)) this.prefix = null;
|
||||
this.localName = in.readUTF();
|
||||
this.owner = in.readUTF();
|
||||
this.name = in.readUTF();
|
||||
this.types = (String[]) in.readObject();
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
if (this.m == null) {
|
||||
try {
|
||||
Class t = ReflectionUtil.forName(this.owner);
|
||||
Class[] p = ReflectionUtil.toTypeArray(this.types);
|
||||
this.m = t.getMethod(this.name, p);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return this.m;
|
||||
}
|
||||
|
||||
public boolean matches(String prefix, String localName) {
|
||||
if (this.prefix != null) {
|
||||
if (prefix == null) return false;
|
||||
if (!this.prefix.equals(prefix)) return false;
|
||||
}
|
||||
return this.localName.equals(localName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Function) {
|
||||
return this.hashCode() == obj.hashCode();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (this.prefix + this.localName).hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-54
@@ -1,54 +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.struts2.el.lang;
|
||||
|
||||
import jakarta.el.ValueExpression;
|
||||
import jakarta.el.VariableMapper;
|
||||
|
||||
public class VariableMapperFactory extends VariableMapper {
|
||||
|
||||
private final VariableMapper target;
|
||||
private VariableMapper momento;
|
||||
|
||||
public VariableMapperFactory(VariableMapper target) {
|
||||
if (target == null) {
|
||||
throw new NullPointerException("Target VariableMapper cannot be null");
|
||||
}
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public VariableMapper create() {
|
||||
return this.momento;
|
||||
}
|
||||
|
||||
public ValueExpression resolveVariable(String variable) {
|
||||
ValueExpression expr = this.target.resolveVariable(variable);
|
||||
if (expr != null) {
|
||||
if (this.momento == null) {
|
||||
this.momento = new VariableMapperImpl();
|
||||
}
|
||||
this.momento.setVariable(variable, expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
public ValueExpression setVariable(String variable, ValueExpression expression) {
|
||||
throw new UnsupportedOperationException("Cannot Set Variables on Factory");
|
||||
}
|
||||
}
|
||||
@@ -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.struts2.el.lang;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.el.ValueExpression;
|
||||
import jakarta.el.VariableMapper;
|
||||
|
||||
public class VariableMapperImpl extends VariableMapper implements Externalizable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Map<String, ValueExpression> vars = new HashMap<String, ValueExpression>();
|
||||
|
||||
public VariableMapperImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ValueExpression resolveVariable(String variable) {
|
||||
return this.vars.get(variable);
|
||||
}
|
||||
|
||||
public ValueExpression setVariable(String variable,
|
||||
ValueExpression expression) {
|
||||
return this.vars.put(variable, expression);
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
this.vars = (Map<String, ValueExpression>) in.readObject();
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeObject(this.vars);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public class ArithmeticNode extends SimpleNode {
|
||||
|
||||
/**
|
||||
* @param i i
|
||||
*/
|
||||
public ArithmeticNode(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return Number.class;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstAnd extends BooleanNode {
|
||||
public AstAnd(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj = children[0].getValue(ctx);
|
||||
Boolean b = coerceToBoolean(obj);
|
||||
if (!b.booleanValue()) {
|
||||
return b;
|
||||
}
|
||||
obj = children[1].getValue(ctx);
|
||||
b = coerceToBoolean(obj);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstBracketSuffix extends SimpleNode {
|
||||
public AstBracketSuffix(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.children[0].getValue(ctx);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstChoice extends SimpleNode {
|
||||
public AstChoice(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object val = this.getValue(ctx);
|
||||
return (val != null) ? val.getClass() : null;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Boolean b0 = coerceToBoolean(obj0);
|
||||
return this.children[((b0.booleanValue() ? 1 : 2))].getValue(ctx);
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstCompositeExpression extends SimpleNode {
|
||||
|
||||
public AstCompositeExpression(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
StringBuffer sb = new StringBuffer(16);
|
||||
Object obj = null;
|
||||
if (this.children != null) {
|
||||
for (int i = 0; i < this.children.length; i++) {
|
||||
obj = this.children[i].getValue(ctx);
|
||||
if (obj != null) {
|
||||
sb.append(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
-54
@@ -1,54 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstDeferredExpression extends SimpleNode {
|
||||
public AstDeferredExpression(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.children[0].getType(ctx);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.children[0].getValue(ctx);
|
||||
}
|
||||
|
||||
public boolean isReadOnly(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.children[0].isReadOnly(ctx);
|
||||
}
|
||||
|
||||
public void setValue(EvaluationContext ctx, Object value)
|
||||
throws ELException {
|
||||
this.children[0].setValue(ctx, value);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELArithmetic;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstDiv extends ArithmeticNode {
|
||||
public AstDiv(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
return ELArithmetic.divide(obj0, obj1);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstDotSuffix extends SimpleNode {
|
||||
public AstDotSuffix(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.image;
|
||||
}
|
||||
}
|
||||
-54
@@ -1,54 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstDynamicExpression extends SimpleNode {
|
||||
public AstDynamicExpression(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.children[0].getType(ctx);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.children[0].getValue(ctx);
|
||||
}
|
||||
|
||||
public boolean isReadOnly(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.children[0].isReadOnly(ctx);
|
||||
}
|
||||
|
||||
public void setValue(EvaluationContext ctx, Object value)
|
||||
throws ELException {
|
||||
this.children[0].setValue(ctx, value);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +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.struts2.el.parser;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstEmpty extends SimpleNode {
|
||||
public AstEmpty(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return Boolean.class;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj = this.children[0].getValue(ctx);
|
||||
if (obj == null) {
|
||||
return Boolean.TRUE;
|
||||
} else if (obj instanceof String) {
|
||||
return Boolean.valueOf(((String) obj).length() == 0);
|
||||
} else if (obj instanceof Object[]) {
|
||||
return Boolean.valueOf(((Object[]) obj).length == 0);
|
||||
} else if (obj instanceof Collection) {
|
||||
return Boolean.valueOf(((Collection) obj).isEmpty());
|
||||
} else if (obj instanceof Map) {
|
||||
return Boolean.valueOf(((Map) obj).isEmpty());
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstEqual extends BooleanNode {
|
||||
public AstEqual(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
return Boolean.valueOf(equals(obj0, obj1));
|
||||
}
|
||||
}
|
||||
@@ -1,39 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstFalse extends BooleanNode {
|
||||
public AstFalse(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +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.struts2.el.parser;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstFloatingPoint extends SimpleNode {
|
||||
public AstFloatingPoint(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
private Number number;
|
||||
|
||||
public Number getFloatingPoint() {
|
||||
if (this.number == null) {
|
||||
try {
|
||||
this.number = new Double(this.image);
|
||||
} catch (ArithmeticException e0) {
|
||||
this.number = new BigDecimal(this.image);
|
||||
}
|
||||
}
|
||||
return this.number;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.getFloatingPoint();
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.getFloatingPoint().getClass();
|
||||
}
|
||||
}
|
||||
@@ -1,134 +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.struts2.el.parser;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.FunctionMapper;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstFunction extends SimpleNode {
|
||||
|
||||
protected String localName = "";
|
||||
|
||||
protected String prefix = "";
|
||||
|
||||
public AstFunction(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public String getLocalName() {
|
||||
return localName;
|
||||
}
|
||||
|
||||
public String getOutputName() {
|
||||
if (this.prefix == null) {
|
||||
return this.localName;
|
||||
} else {
|
||||
return this.prefix + ":" + this.localName;
|
||||
}
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
|
||||
FunctionMapper fnMapper = ctx.getFunctionMapper();
|
||||
|
||||
// quickly validate again for this request
|
||||
if (fnMapper == null) {
|
||||
throw new ELException(MessageFactory.get("error.fnMapper.null"));
|
||||
}
|
||||
Method m = fnMapper.resolveFunction(this.prefix, this.localName);
|
||||
if (m == null) {
|
||||
throw new ELException(MessageFactory.get("error.fnMapper.method",
|
||||
this.getOutputName()));
|
||||
}
|
||||
return m.getReturnType();
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
|
||||
FunctionMapper fnMapper = ctx.getFunctionMapper();
|
||||
|
||||
// quickly validate again for this request
|
||||
if (fnMapper == null) {
|
||||
throw new ELException(MessageFactory.get("error.fnMapper.null"));
|
||||
}
|
||||
Method m = fnMapper.resolveFunction(this.prefix, this.localName);
|
||||
if (m == null) {
|
||||
throw new ELException(MessageFactory.get("error.fnMapper.method",
|
||||
this.getOutputName()));
|
||||
}
|
||||
|
||||
Class[] paramTypes = m.getParameterTypes();
|
||||
Object[] params = null;
|
||||
Object result = null;
|
||||
int numParams = this.jjtGetNumChildren();
|
||||
if (numParams > 0) {
|
||||
params = new Object[numParams];
|
||||
try {
|
||||
for (int i = 0; i < numParams; i++) {
|
||||
params[i] = this.children[i].getValue(ctx);
|
||||
params[i] = coerceToType(params[i], paramTypes[i]);
|
||||
}
|
||||
} catch (ELException ele) {
|
||||
throw new ELException(MessageFactory.get("error.function", this
|
||||
.getOutputName()), ele);
|
||||
}
|
||||
}
|
||||
try {
|
||||
result = m.invoke(null, params);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new ELException(MessageFactory.get("error.function", this
|
||||
.getOutputName()), iae);
|
||||
} catch (InvocationTargetException ite) {
|
||||
throw new ELException(MessageFactory.get("error.function", this
|
||||
.getOutputName()), ite.getCause());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setLocalName(String localName) {
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return ELParserTreeConstants.jjtNodeName[id] + "[" + this.getOutputName() + "]";
|
||||
}
|
||||
}
|
||||
@@ -1,47 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstGreaterThan extends BooleanNode {
|
||||
public AstGreaterThan(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
if (obj0 == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
if (obj1 == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return (compare(obj0, obj1) > 0) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstGreaterThanEqual extends BooleanNode {
|
||||
public AstGreaterThanEqual(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
if (obj0 == obj1) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
if (obj0 == null || obj1 == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return (compare(obj0, obj1) >= 0) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.MethodExpression;
|
||||
import jakarta.el.MethodInfo;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import jakarta.el.ValueExpression;
|
||||
import jakarta.el.VariableMapper;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstIdentifier extends SimpleNode {
|
||||
public AstIdentifier(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx) throws ELException {
|
||||
VariableMapper varMapper = ctx.getVariableMapper();
|
||||
if (varMapper != null) {
|
||||
ValueExpression expr = varMapper.resolveVariable(this.image);
|
||||
if (expr != null) {
|
||||
return expr.getType(ctx.getELContext());
|
||||
}
|
||||
}
|
||||
ctx.setPropertyResolved(false);
|
||||
return ctx.getELResolver().getType(ctx, null, this.image);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx) throws ELException {
|
||||
VariableMapper varMapper = ctx.getVariableMapper();
|
||||
if (varMapper != null) {
|
||||
ValueExpression expr = varMapper.resolveVariable(this.image);
|
||||
if (expr != null) {
|
||||
return expr.getValue(ctx.getELContext());
|
||||
}
|
||||
}
|
||||
ctx.setPropertyResolved(false);
|
||||
return ctx.getELResolver().getValue(ctx, null, this.image);
|
||||
}
|
||||
|
||||
public boolean isReadOnly(EvaluationContext ctx) throws ELException {
|
||||
VariableMapper varMapper = ctx.getVariableMapper();
|
||||
if (varMapper != null) {
|
||||
ValueExpression expr = varMapper.resolveVariable(this.image);
|
||||
if (expr != null) {
|
||||
return expr.isReadOnly(ctx.getELContext());
|
||||
}
|
||||
}
|
||||
ctx.setPropertyResolved(false);
|
||||
return ctx.getELResolver().isReadOnly(ctx, null, this.image);
|
||||
}
|
||||
|
||||
public void setValue(EvaluationContext ctx, Object value)
|
||||
throws ELException {
|
||||
VariableMapper varMapper = ctx.getVariableMapper();
|
||||
if (varMapper != null) {
|
||||
ValueExpression expr = varMapper.resolveVariable(this.image);
|
||||
if (expr != null) {
|
||||
expr.setValue(ctx.getELContext(), value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ctx.setPropertyResolved(false);
|
||||
ctx.getELResolver().setValue(ctx, null, this.image, value);
|
||||
}
|
||||
|
||||
public Object invoke(EvaluationContext ctx, Class[] paramTypes,
|
||||
Object[] paramValues) throws ELException {
|
||||
return this.getMethodExpression(ctx).invoke(ctx.getELContext(), paramValues);
|
||||
}
|
||||
|
||||
|
||||
public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes)
|
||||
throws ELException {
|
||||
return this.getMethodExpression(ctx).getMethodInfo(ctx.getELContext());
|
||||
}
|
||||
|
||||
private final MethodExpression getMethodExpression(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj = null;
|
||||
|
||||
// case A: ValueExpression exists, getValue which must
|
||||
// be a MethodExpression
|
||||
VariableMapper varMapper = ctx.getVariableMapper();
|
||||
ValueExpression ve = null;
|
||||
if (varMapper != null) {
|
||||
ve = varMapper.resolveVariable(this.image);
|
||||
if (ve != null) {
|
||||
obj = ve.getValue(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
// case B: evaluate the identity against the ELResolver, again, must be
|
||||
// a MethodExpression to be able to invoke
|
||||
if (ve == null) {
|
||||
ctx.setPropertyResolved(false);
|
||||
obj = ctx.getELResolver().getValue(ctx, null, this.image);
|
||||
}
|
||||
|
||||
// finally provide helpful hints
|
||||
if (obj instanceof MethodExpression) {
|
||||
return (MethodExpression) obj;
|
||||
} else if (obj == null) {
|
||||
throw new MethodNotFoundException("Identity '" + this.image
|
||||
+ "' was null and was unable to invoke");
|
||||
} else {
|
||||
throw new ELException(
|
||||
"Identity '"
|
||||
+ this.image
|
||||
+ "' does not reference a MethodExpression instance, returned type: "
|
||||
+ obj.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +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.struts2.el.parser;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstInteger extends SimpleNode {
|
||||
public AstInteger(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
private Number number;
|
||||
|
||||
protected Number getInteger() {
|
||||
if (this.number == null) {
|
||||
try {
|
||||
this.number = new Long(this.image);
|
||||
} catch (ArithmeticException e1) {
|
||||
this.number = new BigInteger(this.image);
|
||||
}
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.getInteger().getClass();
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.getInteger();
|
||||
}
|
||||
}
|
||||
@@ -1,46 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstLessThan extends BooleanNode {
|
||||
public AstLessThan(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
if (obj0 == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
if (obj1 == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return (compare(obj0, obj1) < 0) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstLessThanEqual extends BooleanNode {
|
||||
public AstLessThanEqual(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
if (obj0 == obj1) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
if (obj0 == null || obj1 == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return (compare(obj0, obj1) <= 0) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstLiteralExpression extends SimpleNode {
|
||||
public AstLiteralExpression(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx) throws ELException {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx) throws ELException {
|
||||
return this.image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
if (image.indexOf('\\') == -1) {
|
||||
this.image = image;
|
||||
return;
|
||||
}
|
||||
int size = image.length();
|
||||
StringBuffer buf = new StringBuffer(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
char c = image.charAt(i);
|
||||
if (c == '\\' && i + 1 < size) {
|
||||
char c1 = image.charAt(i + 1);
|
||||
if (c1 == '\\' || c1 == '"' || c1 == '\'' || c1 == '#'
|
||||
|| c1 == '$') {
|
||||
c = c1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
buf.append(c);
|
||||
}
|
||||
this.image = buf.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELArithmetic;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstMinus extends ArithmeticNode {
|
||||
public AstMinus(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
return ELArithmetic.subtract(obj0, obj1);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELArithmetic;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstMod extends ArithmeticNode {
|
||||
public AstMod(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
return ELArithmetic.mod(obj0, obj1);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELArithmetic;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstMult extends ArithmeticNode {
|
||||
public AstMult(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
return ELArithmetic.multiply(obj0, obj1);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +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.struts2.el.parser;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstNegative extends SimpleNode {
|
||||
public AstNegative(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return Number.class;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj = this.children[0].getValue(ctx);
|
||||
|
||||
if (obj == null) {
|
||||
return new Long(0);
|
||||
}
|
||||
if (obj instanceof BigDecimal) {
|
||||
return ((BigDecimal) obj).negate();
|
||||
}
|
||||
if (obj instanceof BigInteger) {
|
||||
return ((BigInteger) obj).negate();
|
||||
}
|
||||
if (obj instanceof String) {
|
||||
if (isStringFloat((String) obj)) {
|
||||
return new Double(-Double.parseDouble((String) obj));
|
||||
}
|
||||
return new Long(-Long.parseLong((String) obj));
|
||||
}
|
||||
if (obj instanceof Long) {
|
||||
return new Long(-((Long) obj).longValue());
|
||||
}
|
||||
if (obj instanceof Double) {
|
||||
return new Double(-((Double) obj).doubleValue());
|
||||
}
|
||||
if (obj instanceof Integer) {
|
||||
return new Integer(-((Integer) obj).intValue());
|
||||
}
|
||||
if (obj instanceof Float) {
|
||||
return new Float(-((Float) obj).floatValue());
|
||||
}
|
||||
if (obj instanceof Short) {
|
||||
return new Short((short) -((Short) obj).shortValue());
|
||||
}
|
||||
if (obj instanceof Byte) {
|
||||
return new Byte((byte) -((Byte) obj).byteValue());
|
||||
}
|
||||
Long num = (Long) coerceToNumber(obj, Long.class);
|
||||
return new Long(-num.longValue());
|
||||
}
|
||||
}
|
||||
@@ -1,45 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstNot extends SimpleNode {
|
||||
public AstNot(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return Boolean.class;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj = this.children[0].getValue(ctx);
|
||||
Boolean b = coerceToBoolean(obj);
|
||||
return Boolean.valueOf(!b.booleanValue());
|
||||
}
|
||||
}
|
||||
@@ -1,40 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstNotEqual extends BooleanNode {
|
||||
public AstNotEqual(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
return Boolean.valueOf(!equals(obj0, obj1));
|
||||
}
|
||||
}
|
||||
@@ -1,43 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstNull extends SimpleNode {
|
||||
public AstNull(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstOr extends BooleanNode {
|
||||
public AstOr(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj = this.children[0].getValue(ctx);
|
||||
Boolean b = coerceToBoolean(obj);
|
||||
if (b.booleanValue()) {
|
||||
return b;
|
||||
}
|
||||
obj = this.children[1].getValue(ctx);
|
||||
b = coerceToBoolean(obj);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELArithmetic;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstPlus extends ArithmeticNode {
|
||||
public AstPlus(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
Object obj0 = this.children[0].getValue(ctx);
|
||||
Object obj1 = this.children[1].getValue(ctx);
|
||||
return ELArithmetic.add(obj0, obj1);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstString extends SimpleNode {
|
||||
public AstString(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
private String string;
|
||||
|
||||
public String getString() {
|
||||
if (this.string == null) {
|
||||
this.string = this.image.substring(1, this.image.length() - 1);
|
||||
}
|
||||
return this.string;
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return this.getString();
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
if (image.indexOf('\\') == -1) {
|
||||
this.image = image;
|
||||
return;
|
||||
}
|
||||
int size = image.length();
|
||||
StringBuffer buf = new StringBuffer(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
char c = image.charAt(i);
|
||||
if (c == '\\' && i + 1 < size) {
|
||||
char c1 = image.charAt(i + 1);
|
||||
if (c1 == '\\' || c1 == '"' || c1 == '\'' || c1 == '#'
|
||||
|| c1 == '$') {
|
||||
c = c1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
buf.append(c);
|
||||
}
|
||||
this.image = buf.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstTrue extends BooleanNode {
|
||||
public AstTrue(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,179 +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.struts2.el.parser;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.ELResolver;
|
||||
import jakarta.el.MethodInfo;
|
||||
import jakarta.el.PropertyNotFoundException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELSupport;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
import org.apache.struts2.el.util.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public final class AstValue extends SimpleNode {
|
||||
|
||||
protected static final boolean COERCE_TO_ZERO =
|
||||
Boolean.valueOf(System.getProperty(
|
||||
"org.apache.el.parser.COERCE_TO_ZERO", "true")).booleanValue();
|
||||
|
||||
protected static class Target {
|
||||
protected Object base;
|
||||
|
||||
protected Object property;
|
||||
}
|
||||
|
||||
public AstValue(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx) throws ELException {
|
||||
Target t = getTarget(ctx);
|
||||
ctx.setPropertyResolved(false);
|
||||
return ctx.getELResolver().getType(ctx, t.base, t.property);
|
||||
}
|
||||
|
||||
private final Target getTarget(EvaluationContext ctx) throws ELException {
|
||||
// evaluate expr-a to value-a
|
||||
Object base = this.children[0].getValue(ctx);
|
||||
|
||||
// if our base is null (we know there are more properites to evaluate)
|
||||
if (base == null) {
|
||||
throw new PropertyNotFoundException(MessageFactory.get(
|
||||
"error.unreachable.base", this.children[0].getImage()));
|
||||
}
|
||||
|
||||
// set up our start/end
|
||||
Object property = null;
|
||||
int propCount = this.jjtGetNumChildren() - 1;
|
||||
int i = 1;
|
||||
|
||||
// evaluate any properties before our target
|
||||
ELResolver resolver = ctx.getELResolver();
|
||||
if (propCount > 1) {
|
||||
while (base != null && i < propCount) {
|
||||
property = this.children[i].getValue(ctx);
|
||||
ctx.setPropertyResolved(false);
|
||||
base = resolver.getValue(ctx, base, property);
|
||||
i++;
|
||||
}
|
||||
// if we are in this block, we have more properties to resolve,
|
||||
// but our base was null
|
||||
if (base == null || property == null) {
|
||||
throw new PropertyNotFoundException(MessageFactory.get(
|
||||
"error.unreachable.property", property));
|
||||
}
|
||||
}
|
||||
|
||||
property = this.children[i].getValue(ctx);
|
||||
|
||||
if (property == null) {
|
||||
throw new PropertyNotFoundException(MessageFactory.get(
|
||||
"error.unreachable.property", this.children[i]));
|
||||
}
|
||||
|
||||
Target t = new Target();
|
||||
t.base = base;
|
||||
t.property = property;
|
||||
return t;
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx) throws ELException {
|
||||
Object base = this.children[0].getValue(ctx);
|
||||
int propCount = this.jjtGetNumChildren();
|
||||
int i = 1;
|
||||
Object property = null;
|
||||
ELResolver resolver = ctx.getELResolver();
|
||||
while (base != null && i < propCount) {
|
||||
property = this.children[i].getValue(ctx);
|
||||
if (property == null) {
|
||||
return null;
|
||||
} else {
|
||||
ctx.setPropertyResolved(false);
|
||||
base = resolver.getValue(ctx, base, property);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
public boolean isReadOnly(EvaluationContext ctx) throws ELException {
|
||||
Target t = getTarget(ctx);
|
||||
ctx.setPropertyResolved(false);
|
||||
return ctx.getELResolver().isReadOnly(ctx, t.base, t.property);
|
||||
}
|
||||
|
||||
public void setValue(EvaluationContext ctx, Object value)
|
||||
throws ELException {
|
||||
Target t = getTarget(ctx);
|
||||
ctx.setPropertyResolved(false);
|
||||
ELResolver resolver = ctx.getELResolver();
|
||||
|
||||
// coerce to the expected type
|
||||
Class<?> targetClass = resolver.getType(ctx, t.base, t.property);
|
||||
if (COERCE_TO_ZERO == true
|
||||
|| !isAssignable(value, targetClass)) {
|
||||
value = ELSupport.coerceToType(value, targetClass);
|
||||
}
|
||||
resolver.setValue(ctx, t.base, t.property, value);
|
||||
}
|
||||
|
||||
private boolean isAssignable(Object value, Class<?> targetClass) {
|
||||
if (targetClass == null) {
|
||||
return false;
|
||||
} else if (value != null && targetClass.isPrimitive()) {
|
||||
return false;
|
||||
} else if (value != null && !targetClass.isInstance(value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes)
|
||||
throws ELException {
|
||||
Target t = getTarget(ctx);
|
||||
Method m = ReflectionUtil.getMethod(t.base, t.property, paramTypes);
|
||||
return new MethodInfo(m.getName(), m.getReturnType(), m
|
||||
.getParameterTypes());
|
||||
}
|
||||
|
||||
public Object invoke(EvaluationContext ctx, Class[] paramTypes,
|
||||
Object[] paramValues) throws ELException {
|
||||
Target t = getTarget(ctx);
|
||||
Method m = ReflectionUtil.getMethod(t.base, t.property, paramTypes);
|
||||
Object result = null;
|
||||
try {
|
||||
result = m.invoke(t.base, (Object[]) paramValues);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new ELException(iae);
|
||||
} catch (InvocationTargetException ite) {
|
||||
throw new ELException(ite.getCause());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public class BooleanNode extends SimpleNode {
|
||||
/**
|
||||
* @param i i
|
||||
*/
|
||||
public BooleanNode(int i) {
|
||||
super(i);
|
||||
}
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return Boolean.class;
|
||||
}
|
||||
}
|
||||
@@ -1,223 +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.
|
||||
-->
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>BNF for ELParser.jj</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1 ALIGN=CENTER>BNF for ELParser.jj</H1>
|
||||
<H2 ALIGN=CENTER>NON-TERMINALS</H2>
|
||||
<TABLE>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod1">CompositeExpression</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod2">DeferredExpression</A> | <A HREF="#prod3">DynamicExpression</A> | <A HREF="#prod4">LiteralExpression</A> )* <EOF></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod4">LiteralExpression</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><LITERAL_EXPRESSION></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod2">DeferredExpression</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><START_DEFERRED_EXPRESSION> <A HREF="#prod5">Expression</A> <END_EXPRESSION></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod3">DynamicExpression</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><START_DYNAMIC_EXPRESSION> <A HREF="#prod5">Expression</A> <END_EXPRESSION></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod5">Expression</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod6">Choice</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod6">Choice</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod7">Or</A> ( <QUESTIONMARK> <A HREF="#prod6">Choice</A> <COLON> <A HREF="#prod6">Choice</A> )*</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod7">Or</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod8">And</A> ( ( <OR0> | <OR1> ) <A HREF="#prod8">And</A> )*</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod8">And</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod9">Equality</A> ( ( <AND0> | <AND1> ) <A HREF="#prod9">Equality</A> )*</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod9">Equality</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod10">Compare</A> ( ( ( <EQ0> | <EQ1> ) <A HREF="#prod10">Compare</A> ) | ( ( <NE0> | <NE1> ) <A HREF="#prod10">Compare</A> ) )*</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod10">Compare</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod11">Math</A> ( ( ( <LT0> | <LT1> ) <A HREF="#prod11">Math</A> ) | ( ( <GT0> | <GT1> ) <A HREF="#prod11">Math</A> ) | ( ( <LE0> | <LE1> ) <A HREF="#prod11">Math</A> ) | ( ( <GE0> | <GE1> ) <A HREF="#prod11">Math</A> ) )*</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod11">Math</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod12">Multiplication</A> ( ( <PLUS> <A HREF="#prod12">Multiplication</A> ) | ( <MINUS> <A HREF="#prod12">Multiplication</A> ) )*</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod12">Multiplication</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod13">Unary</A> ( ( <MULT> <A HREF="#prod13">Unary</A> ) | ( <DIV> <A HREF="#prod13">Unary</A> ) | ( ( <MOD0> | <MOD1> ) <A HREF="#prod13">Unary</A> ) )*</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod13">Unary</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><MINUS> <A HREF="#prod13">Unary</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE>( <NOT0> | <NOT1> ) <A HREF="#prod13">Unary</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><EMPTY> <A HREF="#prod13">Unary</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod14">Value</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod14">Value</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod15">ValuePrefix</A> ( <A HREF="#prod16">ValueSuffix</A> )* )</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod15">ValuePrefix</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod17">Literal</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">NonLiteral</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod16">ValueSuffix</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod19">DotSuffix</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod20">BracketSuffix</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod19">DotSuffix</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><DOT> <IDENTIFIER></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod20">BracketSuffix</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><LBRACK> <A HREF="#prod5">Expression</A> <RBRACK></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod18">NonLiteral</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><LPAREN> <A HREF="#prod5">Expression</A> <RPAREN></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod21">Function</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod22">Identifier</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod22">Identifier</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><IDENTIFIER></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod21">Function</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><IDENTIFIER> ( <FUNCTIONSUFFIX> )? <LPAREN> ( <A HREF="#prod5">Expression</A> ( <COMMA> <A HREF="#prod5">Expression</A> )* )? <RPAREN></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod17">Literal</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod23">Boolean</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod24">FloatingPoint</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod25">Integer</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod26">String</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod27">Null</A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod23">Boolean</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><TRUE></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><FALSE></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod24">FloatingPoint</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><FLOATING_POINT_LITERAL></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod25">Integer</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><INTEGER_LITERAL></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod26">String</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><STRING_LITERAL></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod27">Null</A></TD>
|
||||
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
|
||||
<TD ALIGN=LEFT VALIGN=BASELINE><NULL></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,470 +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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Author: Jacob Hookom
|
||||
Email: jacob at hookom.net
|
||||
*/
|
||||
|
||||
/* == Option Declaration == */
|
||||
options
|
||||
{
|
||||
STATIC=false;
|
||||
NODE_PREFIX="Ast";
|
||||
VISITOR_EXCEPTION="jakarta.el.ELException";
|
||||
VISITOR=false;
|
||||
MULTI=true;
|
||||
NODE_DEFAULT_VOID=true;
|
||||
JAVA_UNICODE_ESCAPE=false;
|
||||
UNICODE_INPUT=true;
|
||||
BUILD_NODE_FILES=true;
|
||||
}
|
||||
|
||||
/* == Parser Declaration == */
|
||||
PARSER_BEGIN( ELParser )
|
||||
package org.apache.el.parser;
|
||||
import java.io.StringReader;
|
||||
import jakarta.el.ELException;
|
||||
public class ELParser
|
||||
{
|
||||
public static Node parse(String ref) throws ELException
|
||||
{
|
||||
try {
|
||||
return (new ELParser(new StringReader(ref))).CompositeExpression();
|
||||
} catch (ParseException pe) {
|
||||
throw new ELException(pe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
PARSER_END( ELParser )
|
||||
|
||||
/*
|
||||
* CompositeExpression
|
||||
* Allow most flexible parsing, restrict by examining
|
||||
* type of returned node
|
||||
*/
|
||||
AstCompositeExpression CompositeExpression() #CompositeExpression : {}
|
||||
{
|
||||
(DeferredExpression() | DynamicExpression() | LiteralExpression())* <EOF> { return jjtThis; }
|
||||
}
|
||||
|
||||
/*
|
||||
* LiteralExpression
|
||||
* Non-EL Expression blocks
|
||||
*/
|
||||
void LiteralExpression() #LiteralExpression : { Token t = null; }
|
||||
{
|
||||
t=<LITERAL_EXPRESSION> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* DeferredExpression
|
||||
* #{..} Expressions
|
||||
*/
|
||||
void DeferredExpression() #DeferredExpression : {}
|
||||
{
|
||||
<START_DEFERRED_EXPRESSION> Expression() <END_EXPRESSION>
|
||||
}
|
||||
|
||||
/*
|
||||
* DynamicExpression
|
||||
* ${..} Expressions
|
||||
*/
|
||||
void DynamicExpression() #DynamicExpression : {}
|
||||
{
|
||||
<START_DYNAMIC_EXPRESSION> Expression() <END_EXPRESSION>
|
||||
}
|
||||
|
||||
/*
|
||||
* Expression
|
||||
* EL Expression Language Root, goes to Choice
|
||||
*/
|
||||
void Expression() : {}
|
||||
{
|
||||
Choice()
|
||||
}
|
||||
|
||||
/*
|
||||
* Choice
|
||||
* For Choice markup a ? b : c, then Or
|
||||
*/
|
||||
void Choice() : {}
|
||||
{
|
||||
Or() (LOOKAHEAD(3) <QUESTIONMARK> Choice() <COLON> Choice() #Choice(3))*
|
||||
}
|
||||
|
||||
/*
|
||||
* Or
|
||||
* For 'or' '||', then And
|
||||
*/
|
||||
void Or() : {}
|
||||
{
|
||||
And() ((<OR0>|<OR1>) And() #Or(2))*
|
||||
}
|
||||
|
||||
/*
|
||||
* And
|
||||
* For 'and' '&&', then Equality
|
||||
*/
|
||||
void And() : {}
|
||||
{
|
||||
Equality() ((<AND0>|<AND1>) Equality() #And(2))*
|
||||
}
|
||||
|
||||
/*
|
||||
* Equality
|
||||
* For '==' 'eq' '!=' 'ne', then Compare
|
||||
*/
|
||||
void Equality() : {}
|
||||
{
|
||||
Compare()
|
||||
(
|
||||
((<EQ0>|<EQ1>) Compare() #Equal(2))
|
||||
|
|
||||
((<NE0>|<NE1>) Compare() #NotEqual(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare
|
||||
* For a bunch of them, then Math
|
||||
*/
|
||||
void Compare() : {}
|
||||
{
|
||||
Math()
|
||||
(
|
||||
((<LT0>|<LT1>) Math() #LessThan(2))
|
||||
|
|
||||
((<GT0>|<GT1>) Math() #GreaterThan(2))
|
||||
|
|
||||
((<LE0>|<LE1>) Math() #LessThanEqual(2))
|
||||
|
|
||||
((<GE0>|<GE1>) Math() #GreaterThanEqual(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Math
|
||||
* For '+' '-', then Multiplication
|
||||
*/
|
||||
void Math() : {}
|
||||
{
|
||||
Multiplication()
|
||||
(
|
||||
(<PLUS> Multiplication() #Plus(2))
|
||||
|
|
||||
(<MINUS> Multiplication() #Minus(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
* For a bunch of them, then Unary
|
||||
*/
|
||||
void Multiplication() : {}
|
||||
{
|
||||
Unary()
|
||||
(
|
||||
(<MULT> Unary() #Mult(2))
|
||||
|
|
||||
((<DIV0>|<DIV1>) Unary() #Div(2))
|
||||
|
|
||||
((<MOD0>|<MOD1>) Unary() #Mod(2))
|
||||
)*
|
||||
}
|
||||
|
||||
/*
|
||||
* Unary
|
||||
* For '-' '!' 'not' 'empty', then Value
|
||||
*/
|
||||
void Unary() : {}
|
||||
{
|
||||
<MINUS> Unary() #Negative
|
||||
|
|
||||
(<NOT0>|<NOT1>) Unary() #Not
|
||||
|
|
||||
<EMPTY> Unary() #Empty
|
||||
|
|
||||
Value()
|
||||
}
|
||||
|
||||
/*
|
||||
* Value
|
||||
* Defines Prefix plus zero or more Suffixes
|
||||
*/
|
||||
void Value() : {}
|
||||
{
|
||||
(ValuePrefix() (ValueSuffix())*) #Value(>1)
|
||||
}
|
||||
|
||||
/*
|
||||
* ValuePrefix
|
||||
* For Literals, Variables, and Functions
|
||||
*/
|
||||
void ValuePrefix() : {}
|
||||
{
|
||||
Literal()
|
||||
| NonLiteral()
|
||||
}
|
||||
|
||||
/*
|
||||
* ValueSuffix
|
||||
* Either dot or bracket notation
|
||||
*/
|
||||
void ValueSuffix() : {}
|
||||
{
|
||||
DotSuffix() | BracketSuffix()
|
||||
}
|
||||
|
||||
/*
|
||||
* DotSuffix
|
||||
* Dot Property
|
||||
*/
|
||||
void DotSuffix() #DotSuffix : { Token t = null; }
|
||||
{
|
||||
<DOT> t=<IDENTIFIER> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* BracketSuffix
|
||||
* Sub Expression Suffix
|
||||
*/
|
||||
void BracketSuffix() #BracketSuffix : {}
|
||||
{
|
||||
<LBRACK> Expression() <RBRACK>
|
||||
}
|
||||
|
||||
/*
|
||||
* NonLiteral
|
||||
* For Grouped Operations, Identifiers, and Functions
|
||||
*/
|
||||
void NonLiteral() : {}
|
||||
{
|
||||
<LPAREN> Expression() <RPAREN>
|
||||
| LOOKAHEAD((<IDENTIFIER> <COLON>)? <IDENTIFIER> <LPAREN>) Function()
|
||||
| Identifier()
|
||||
}
|
||||
|
||||
/*
|
||||
* Identifier
|
||||
* Java Language Identifier
|
||||
*/
|
||||
void Identifier() #Identifier : { Token t = null; }
|
||||
{
|
||||
t=<IDENTIFIER> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* Function
|
||||
* Namespace:Name(a,b,c)
|
||||
*/
|
||||
void Function() #Function :
|
||||
{
|
||||
Token t0 = null;
|
||||
Token t1 = null;
|
||||
}
|
||||
{
|
||||
(LOOKAHEAD(2) t0=<IDENTIFIER> <COLON>)? t1=<IDENTIFIER>
|
||||
{
|
||||
if (t0 != null) {
|
||||
jjtThis.setPrefix(t0.image);
|
||||
jjtThis.setLocalName(t1.image);
|
||||
} else {
|
||||
jjtThis.setLocalName(t1.image);
|
||||
}
|
||||
}
|
||||
<LPAREN> (Expression() (<COMMA> Expression())*)? <RPAREN>
|
||||
}
|
||||
|
||||
/*
|
||||
* Literal
|
||||
* Reserved Keywords
|
||||
*/
|
||||
void Literal() : {}
|
||||
{
|
||||
Boolean()
|
||||
| FloatingPoint()
|
||||
| Integer()
|
||||
| String()
|
||||
| Null()
|
||||
}
|
||||
|
||||
/*
|
||||
* Boolean
|
||||
* For 'true' 'false'
|
||||
*/
|
||||
void Boolean() : {}
|
||||
{
|
||||
<TRUE> #True
|
||||
| <FALSE> #False
|
||||
}
|
||||
|
||||
/*
|
||||
* FloatinPoint
|
||||
* For Decimal and Floating Point Literals
|
||||
*/
|
||||
void FloatingPoint() #FloatingPoint : { Token t = null; }
|
||||
{
|
||||
t=<FLOATING_POINT_LITERAL> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* Integer
|
||||
* For Simple Numeric Literals
|
||||
*/
|
||||
void Integer() #Integer : { Token t = null; }
|
||||
{
|
||||
t=<INTEGER_LITERAL> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* String
|
||||
* For Quoted Literals
|
||||
*/
|
||||
void String() #String : { Token t = null; }
|
||||
{
|
||||
t=<STRING_LITERAL> { jjtThis.setImage(t.image); }
|
||||
}
|
||||
|
||||
/*
|
||||
* Null
|
||||
* For 'null'
|
||||
*/
|
||||
void Null() #Null : {}
|
||||
{
|
||||
<NULL>
|
||||
}
|
||||
|
||||
|
||||
/* ==================================================================================== */
|
||||
<DEFAULT> TOKEN :
|
||||
{
|
||||
< LITERAL_EXPRESSION:
|
||||
((~["\\", "$", "#"])
|
||||
| ("\\" ("\\" | "$" | "#"))
|
||||
| ("$" ~["{", "$"])
|
||||
| ("#" ~["{", "#"])
|
||||
)+
|
||||
| "$"
|
||||
| "#"
|
||||
>
|
||||
|
|
||||
< START_DYNAMIC_EXPRESSION: "${" > : IN_EXPRESSION
|
||||
|
|
||||
< START_DEFERRED_EXPRESSION: "#{" > : IN_EXPRESSION
|
||||
}
|
||||
|
||||
<DEFAULT> SKIP : { "\\" }
|
||||
|
||||
<IN_EXPRESSION> SKIP : { " " | "\t" | "\n" | "\r" }
|
||||
|
||||
<IN_EXPRESSION> TOKEN :
|
||||
{
|
||||
< INTEGER_LITERAL: ["0"-"9"] (["0"-"9"])* >
|
||||
| < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)?
|
||||
| "." (["0"-"9"])+ (<EXPONENT>)?
|
||||
| (["0"-"9"])+ <EXPONENT>
|
||||
>
|
||||
| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
|
||||
| < STRING_LITERAL: ("\"" ((~["\"","\\"])
|
||||
| ("\\" ( ["\\","\""] )))* "\"")
|
||||
| ("\'" ((~["\'","\\"])
|
||||
| ("\\" ( ["\\","\'"] )))* "\'")
|
||||
>
|
||||
| < BADLY_ESCAPED_STRING_LITERAL: ("\"" (~["\"","\\"])* ("\\" ( ~["\\","\""] )))
|
||||
| ("\'" (~["\'","\\"])* ("\\" ( ~["\\","\'"] )))
|
||||
>
|
||||
| < TRUE : "true" >
|
||||
| < FALSE : "false" >
|
||||
| < NULL : "null" >
|
||||
| < END_EXPRESSION : "}" > : DEFAULT
|
||||
| < DOT : "." >
|
||||
| < LPAREN : "(" >
|
||||
| < RPAREN : ")" >
|
||||
| < LBRACK : "[" >
|
||||
| < RBRACK : "]" >
|
||||
| < COLON : ":" >
|
||||
| < COMMA : "," >
|
||||
| < GT0 : ">" >
|
||||
| < GT1 : "gt" >
|
||||
| < LT0 : "<" >
|
||||
| < LT1 : "lt" >
|
||||
| < GE0 : ">=" >
|
||||
| < GE1 : "ge" >
|
||||
| < LE0 : "<=" >
|
||||
| < LE1 : "le" >
|
||||
| < EQ0 : "==" >
|
||||
| < EQ1 : "eq" >
|
||||
| < NE0 : "!=" >
|
||||
| < NE1 : "ne" >
|
||||
| < NOT0 : "!" >
|
||||
| < NOT1 : "not" >
|
||||
| < AND0 : "&&" >
|
||||
| < AND1 : "and" >
|
||||
| < OR0 : "||" >
|
||||
| < OR1 : "or" >
|
||||
| < EMPTY : "empty" >
|
||||
| < INSTANCEOF : "instanceof" >
|
||||
| < MULT : "*" >
|
||||
| < PLUS : "+" >
|
||||
| < MINUS : "-" >
|
||||
| < QUESTIONMARK : "?" >
|
||||
| < DIV0 : "/" >
|
||||
| < DIV1 : "div" >
|
||||
| < MOD0 : "%" >
|
||||
| < MOD1 : "mod" >
|
||||
| < IDENTIFIER : (<LETTER>|<IMPL_OBJ_START>) (<LETTER>|<DIGIT>)* >
|
||||
| < FUNCTIONSUFFIX : (<IDENTIFIER>) >
|
||||
| < #IMPL_OBJ_START: "#" >
|
||||
| < #LETTER:
|
||||
[
|
||||
"\u0024",
|
||||
"\u0041"-"\u005a",
|
||||
"\u005f",
|
||||
"\u0061"-"\u007a",
|
||||
"\u00c0"-"\u00d6",
|
||||
"\u00d8"-"\u00f6",
|
||||
"\u00f8"-"\u00ff",
|
||||
"\u0100"-"\u1fff",
|
||||
"\u3040"-"\u318f",
|
||||
"\u3300"-"\u337f",
|
||||
"\u3400"-"\u3d2d",
|
||||
"\u4e00"-"\u9fff",
|
||||
"\uf900"-"\ufaff"
|
||||
]
|
||||
>
|
||||
| < #DIGIT:
|
||||
[
|
||||
"\u0030"-"\u0039",
|
||||
"\u0660"-"\u0669",
|
||||
"\u06f0"-"\u06f9",
|
||||
"\u0966"-"\u096f",
|
||||
"\u09e6"-"\u09ef",
|
||||
"\u0a66"-"\u0a6f",
|
||||
"\u0ae6"-"\u0aef",
|
||||
"\u0b66"-"\u0b6f",
|
||||
"\u0be7"-"\u0bef",
|
||||
"\u0c66"-"\u0c6f",
|
||||
"\u0ce6"-"\u0cef",
|
||||
"\u0d66"-"\u0d6f",
|
||||
"\u0e50"-"\u0e59",
|
||||
"\u0ed0"-"\u0ed9",
|
||||
"\u1040"-"\u1049"
|
||||
]
|
||||
>
|
||||
| < ILLEGAL_CHARACTER: (~[]) >
|
||||
}
|
||||
-206
@@ -1,206 +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.
|
||||
*/
|
||||
/* Generated By:JJTree&JavaCC: Do not edit this line. ELParserConstants.java */
|
||||
package org.apache.struts2.el.parser;
|
||||
|
||||
|
||||
/**
|
||||
* Token literal values and constants.
|
||||
* Generated by org.javacc.parser.OtherFilesGen#start()
|
||||
*/
|
||||
public interface ELParserConstants {
|
||||
|
||||
/** End of File. */
|
||||
int EOF = 0;
|
||||
/** RegularExpression Id. */
|
||||
int LITERAL_EXPRESSION = 1;
|
||||
/** RegularExpression Id. */
|
||||
int START_DYNAMIC_EXPRESSION = 2;
|
||||
/** RegularExpression Id. */
|
||||
int START_DEFERRED_EXPRESSION = 3;
|
||||
/** RegularExpression Id. */
|
||||
int INTEGER_LITERAL = 9;
|
||||
/** RegularExpression Id. */
|
||||
int FLOATING_POINT_LITERAL = 10;
|
||||
/** RegularExpression Id. */
|
||||
int EXPONENT = 11;
|
||||
/** RegularExpression Id. */
|
||||
int STRING_LITERAL = 12;
|
||||
/** RegularExpression Id. */
|
||||
int BADLY_ESCAPED_STRING_LITERAL = 13;
|
||||
/** RegularExpression Id. */
|
||||
int TRUE = 14;
|
||||
/** RegularExpression Id. */
|
||||
int FALSE = 15;
|
||||
/** RegularExpression Id. */
|
||||
int NULL = 16;
|
||||
/** RegularExpression Id. */
|
||||
int END_EXPRESSION = 17;
|
||||
/** RegularExpression Id. */
|
||||
int DOT = 18;
|
||||
/** RegularExpression Id. */
|
||||
int LPAREN = 19;
|
||||
/** RegularExpression Id. */
|
||||
int RPAREN = 20;
|
||||
/** RegularExpression Id. */
|
||||
int LBRACK = 21;
|
||||
/** RegularExpression Id. */
|
||||
int RBRACK = 22;
|
||||
/** RegularExpression Id. */
|
||||
int COLON = 23;
|
||||
/** RegularExpression Id. */
|
||||
int COMMA = 24;
|
||||
/** RegularExpression Id. */
|
||||
int GT0 = 25;
|
||||
/** RegularExpression Id. */
|
||||
int GT1 = 26;
|
||||
/** RegularExpression Id. */
|
||||
int LT0 = 27;
|
||||
/** RegularExpression Id. */
|
||||
int LT1 = 28;
|
||||
/** RegularExpression Id. */
|
||||
int GE0 = 29;
|
||||
/** RegularExpression Id. */
|
||||
int GE1 = 30;
|
||||
/** RegularExpression Id. */
|
||||
int LE0 = 31;
|
||||
/** RegularExpression Id. */
|
||||
int LE1 = 32;
|
||||
/** RegularExpression Id. */
|
||||
int EQ0 = 33;
|
||||
/** RegularExpression Id. */
|
||||
int EQ1 = 34;
|
||||
/** RegularExpression Id. */
|
||||
int NE0 = 35;
|
||||
/** RegularExpression Id. */
|
||||
int NE1 = 36;
|
||||
/** RegularExpression Id. */
|
||||
int NOT0 = 37;
|
||||
/** RegularExpression Id. */
|
||||
int NOT1 = 38;
|
||||
/** RegularExpression Id. */
|
||||
int AND0 = 39;
|
||||
/** RegularExpression Id. */
|
||||
int AND1 = 40;
|
||||
/** RegularExpression Id. */
|
||||
int OR0 = 41;
|
||||
/** RegularExpression Id. */
|
||||
int OR1 = 42;
|
||||
/** RegularExpression Id. */
|
||||
int EMPTY = 43;
|
||||
/** RegularExpression Id. */
|
||||
int INSTANCEOF = 44;
|
||||
/** RegularExpression Id. */
|
||||
int MULT = 45;
|
||||
/** RegularExpression Id. */
|
||||
int PLUS = 46;
|
||||
/** RegularExpression Id. */
|
||||
int MINUS = 47;
|
||||
/** RegularExpression Id. */
|
||||
int QUESTIONMARK = 48;
|
||||
/** RegularExpression Id. */
|
||||
int DIV0 = 49;
|
||||
/** RegularExpression Id. */
|
||||
int DIV1 = 50;
|
||||
/** RegularExpression Id. */
|
||||
int MOD0 = 51;
|
||||
/** RegularExpression Id. */
|
||||
int MOD1 = 52;
|
||||
/** RegularExpression Id. */
|
||||
int IDENTIFIER = 53;
|
||||
/** RegularExpression Id. */
|
||||
int FUNCTIONSUFFIX = 54;
|
||||
/** RegularExpression Id. */
|
||||
int IMPL_OBJ_START = 55;
|
||||
/** RegularExpression Id. */
|
||||
int LETTER = 56;
|
||||
/** RegularExpression Id. */
|
||||
int DIGIT = 57;
|
||||
/** RegularExpression Id. */
|
||||
int ILLEGAL_CHARACTER = 58;
|
||||
|
||||
/** Lexical state. */
|
||||
int DEFAULT = 0;
|
||||
/** Lexical state. */
|
||||
int IN_EXPRESSION = 1;
|
||||
|
||||
/** Literal token values. */
|
||||
String[] tokenImage = {
|
||||
"<EOF>",
|
||||
"<LITERAL_EXPRESSION>",
|
||||
"\"${\"",
|
||||
"\"#{\"",
|
||||
"\"\\\\\"",
|
||||
"\" \"",
|
||||
"\"\\t\"",
|
||||
"\"\\n\"",
|
||||
"\"\\r\"",
|
||||
"<INTEGER_LITERAL>",
|
||||
"<FLOATING_POINT_LITERAL>",
|
||||
"<EXPONENT>",
|
||||
"<STRING_LITERAL>",
|
||||
"<BADLY_ESCAPED_STRING_LITERAL>",
|
||||
"\"true\"",
|
||||
"\"false\"",
|
||||
"\"null\"",
|
||||
"\"}\"",
|
||||
"\".\"",
|
||||
"\"(\"",
|
||||
"\")\"",
|
||||
"\"[\"",
|
||||
"\"]\"",
|
||||
"\":\"",
|
||||
"\",\"",
|
||||
"\">\"",
|
||||
"\"gt\"",
|
||||
"\"<\"",
|
||||
"\"lt\"",
|
||||
"\">=\"",
|
||||
"\"ge\"",
|
||||
"\"<=\"",
|
||||
"\"le\"",
|
||||
"\"==\"",
|
||||
"\"eq\"",
|
||||
"\"!=\"",
|
||||
"\"ne\"",
|
||||
"\"!\"",
|
||||
"\"not\"",
|
||||
"\"&&\"",
|
||||
"\"and\"",
|
||||
"\"||\"",
|
||||
"\"or\"",
|
||||
"\"empty\"",
|
||||
"\"instanceof\"",
|
||||
"\"*\"",
|
||||
"\"+\"",
|
||||
"\"-\"",
|
||||
"\"?\"",
|
||||
"\"/\"",
|
||||
"\"div\"",
|
||||
"\"%\"",
|
||||
"\"mod\"",
|
||||
"<IDENTIFIER>",
|
||||
"<FUNCTIONSUFFIX>",
|
||||
"\"#\"",
|
||||
"<LETTER>",
|
||||
"<DIGIT>",
|
||||
"<ILLEGAL_CHARACTER>",
|
||||
};
|
||||
|
||||
}
|
||||
-1343
File diff suppressed because it is too large
Load Diff
-95
@@ -1,95 +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.
|
||||
*/
|
||||
/* Generated By:JavaCC: Do not edit this line. ELParserTreeConstants.java Version 4.1 */
|
||||
package org.apache.struts2.el.parser;
|
||||
|
||||
public interface ELParserTreeConstants
|
||||
{
|
||||
public int JJTCOMPOSITEEXPRESSION = 0;
|
||||
public int JJTLITERALEXPRESSION = 1;
|
||||
public int JJTDEFERREDEXPRESSION = 2;
|
||||
public int JJTDYNAMICEXPRESSION = 3;
|
||||
public int JJTVOID = 4;
|
||||
public int JJTCHOICE = 5;
|
||||
public int JJTOR = 6;
|
||||
public int JJTAND = 7;
|
||||
public int JJTEQUAL = 8;
|
||||
public int JJTNOTEQUAL = 9;
|
||||
public int JJTLESSTHAN = 10;
|
||||
public int JJTGREATERTHAN = 11;
|
||||
public int JJTLESSTHANEQUAL = 12;
|
||||
public int JJTGREATERTHANEQUAL = 13;
|
||||
public int JJTPLUS = 14;
|
||||
public int JJTMINUS = 15;
|
||||
public int JJTMULT = 16;
|
||||
public int JJTDIV = 17;
|
||||
public int JJTMOD = 18;
|
||||
public int JJTNEGATIVE = 19;
|
||||
public int JJTNOT = 20;
|
||||
public int JJTEMPTY = 21;
|
||||
public int JJTVALUE = 22;
|
||||
public int JJTDOTSUFFIX = 23;
|
||||
public int JJTBRACKETSUFFIX = 24;
|
||||
public int JJTIDENTIFIER = 25;
|
||||
public int JJTFUNCTION = 26;
|
||||
public int JJTTRUE = 27;
|
||||
public int JJTFALSE = 28;
|
||||
public int JJTFLOATINGPOINT = 29;
|
||||
public int JJTINTEGER = 30;
|
||||
public int JJTSTRING = 31;
|
||||
public int JJTNULL = 32;
|
||||
|
||||
|
||||
public String[] jjtNodeName = {
|
||||
"CompositeExpression",
|
||||
"LiteralExpression",
|
||||
"DeferredExpression",
|
||||
"DynamicExpression",
|
||||
"void",
|
||||
"Choice",
|
||||
"Or",
|
||||
"And",
|
||||
"Equal",
|
||||
"NotEqual",
|
||||
"LessThan",
|
||||
"GreaterThan",
|
||||
"LessThanEqual",
|
||||
"GreaterThanEqual",
|
||||
"Plus",
|
||||
"Minus",
|
||||
"Mult",
|
||||
"Div",
|
||||
"Mod",
|
||||
"Negative",
|
||||
"Not",
|
||||
"Empty",
|
||||
"Value",
|
||||
"DotSuffix",
|
||||
"BracketSuffix",
|
||||
"Identifier",
|
||||
"Function",
|
||||
"True",
|
||||
"False",
|
||||
"FloatingPoint",
|
||||
"Integer",
|
||||
"String",
|
||||
"Null",
|
||||
};
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=3f8a43fb30bdf082a70de7eb7b15fdf1 (do not edit this line) */
|
||||
@@ -1,141 +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.
|
||||
*/
|
||||
/* Generated By:JavaCC: Do not edit this line. JJTELParserState.java Version 4.1 */
|
||||
package org.apache.struts2.el.parser;
|
||||
|
||||
public class JJTELParserState {
|
||||
private java.util.List nodes;
|
||||
private java.util.List marks;
|
||||
|
||||
private int sp; // number of nodes on stack
|
||||
private int mk; // current mark
|
||||
private boolean node_created;
|
||||
|
||||
public JJTELParserState() {
|
||||
nodes = new java.util.ArrayList();
|
||||
marks = new java.util.ArrayList();
|
||||
sp = 0;
|
||||
mk = 0;
|
||||
}
|
||||
|
||||
/* Determines whether the current node was actually closed and
|
||||
pushed. This should only be called in the final user action of a
|
||||
node scope. */
|
||||
public boolean nodeCreated() {
|
||||
return node_created;
|
||||
}
|
||||
|
||||
/* Call this to reinitialize the node stack. It is called
|
||||
automatically by the parser's ReInit() method. */
|
||||
public void reset() {
|
||||
nodes.clear();
|
||||
marks.clear();
|
||||
sp = 0;
|
||||
mk = 0;
|
||||
}
|
||||
|
||||
/* Returns the root node of the AST. It only makes sense to call
|
||||
this after a successful parse. */
|
||||
public Node rootNode() {
|
||||
return (Node)nodes.get(0);
|
||||
}
|
||||
|
||||
/* Pushes a node on to the stack. */
|
||||
public void pushNode(Node n) {
|
||||
nodes.add(n);
|
||||
++sp;
|
||||
}
|
||||
|
||||
/* Returns the node on the top of the stack, and remove it from the
|
||||
stack. */
|
||||
public Node popNode() {
|
||||
if (--sp < mk) {
|
||||
mk = ((Integer)marks.remove(marks.size()-1)).intValue();
|
||||
}
|
||||
return (Node)nodes.remove(nodes.size()-1);
|
||||
}
|
||||
|
||||
/* Returns the node currently on the top of the stack. */
|
||||
public Node peekNode() {
|
||||
return (Node)nodes.get(nodes.size()-1);
|
||||
}
|
||||
|
||||
/* Returns the number of children on the stack in the current node
|
||||
scope. */
|
||||
public int nodeArity() {
|
||||
return sp - mk;
|
||||
}
|
||||
|
||||
|
||||
public void clearNodeScope(Node n) {
|
||||
while (sp > mk) {
|
||||
popNode();
|
||||
}
|
||||
mk = ((Integer)marks.remove(marks.size()-1)).intValue();
|
||||
}
|
||||
|
||||
|
||||
public void openNodeScope(Node n) {
|
||||
marks.add(new Integer(mk));
|
||||
mk = sp;
|
||||
n.jjtOpen();
|
||||
}
|
||||
|
||||
|
||||
/* A definite node is constructed from a specified number of
|
||||
children. That number of nodes are popped from the stack and
|
||||
made the children of the definite node. Then the definite node
|
||||
is pushed on to the stack. */
|
||||
public void closeNodeScope(Node n, int num) {
|
||||
mk = ((Integer)marks.remove(marks.size()-1)).intValue();
|
||||
while (num-- > 0) {
|
||||
Node c = popNode();
|
||||
c.jjtSetParent(n);
|
||||
n.jjtAddChild(c, num);
|
||||
}
|
||||
n.jjtClose();
|
||||
pushNode(n);
|
||||
node_created = true;
|
||||
}
|
||||
|
||||
|
||||
/* A conditional node is constructed if its condition is true. All
|
||||
the nodes that have been pushed since the node was opened are
|
||||
made children of the conditional node, which is then pushed
|
||||
on to the stack. If the condition is false the node is not
|
||||
constructed and they are left on the stack. */
|
||||
public void closeNodeScope(Node n, boolean condition) {
|
||||
if (condition) {
|
||||
int a = nodeArity();
|
||||
mk = ((Integer)marks.remove(marks.size()-1)).intValue();
|
||||
while (a-- > 0) {
|
||||
Node c = popNode();
|
||||
c.jjtSetParent(n);
|
||||
n.jjtAddChild(c, a);
|
||||
}
|
||||
n.jjtClose();
|
||||
pushNode(n);
|
||||
node_created = true;
|
||||
} else {
|
||||
mk = ((Integer)marks.remove(marks.size()-1)).intValue();
|
||||
node_created = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=9497b88da93266c314e4e50d08492496 (do not edit this line) */
|
||||
@@ -1,97 +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.struts2.el.parser;
|
||||
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.MethodInfo;
|
||||
|
||||
/* All AST nodes must implement this interface. It provides basic
|
||||
machinery for constructing the parent and child relationships
|
||||
between nodes. */
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public interface Node {
|
||||
|
||||
/**
|
||||
* This method is called after the node has been made the current
|
||||
* node. It indicates that child nodes can now be added to it.
|
||||
*/
|
||||
public void jjtOpen();
|
||||
|
||||
/**
|
||||
* This method is called after all the child nodes have been
|
||||
* added.
|
||||
*/
|
||||
public void jjtClose();
|
||||
|
||||
/**
|
||||
* This pair of methods are used to inform the node of its
|
||||
* parent.
|
||||
*
|
||||
* @param n the node
|
||||
*/
|
||||
public void jjtSetParent(Node n);
|
||||
|
||||
public Node jjtGetParent();
|
||||
|
||||
/**
|
||||
* This method tells the node to add its argument to the node's
|
||||
* list of children.
|
||||
*
|
||||
* @param n the node
|
||||
* @param i i
|
||||
*/
|
||||
public void jjtAddChild(Node n, int i);
|
||||
|
||||
/**
|
||||
* This method returns a child node. The children are numbered
|
||||
* from zero, left to right.
|
||||
*
|
||||
* @param i i
|
||||
*
|
||||
* @return child node
|
||||
*/
|
||||
public Node jjtGetChild(int i);
|
||||
|
||||
/**
|
||||
* @return the number of children the node has.
|
||||
*/
|
||||
public int jjtGetNumChildren();
|
||||
|
||||
public String getImage();
|
||||
|
||||
public Object getValue(EvaluationContext ctx) throws ELException;
|
||||
|
||||
public void setValue(EvaluationContext ctx, Object value) throws ELException;
|
||||
|
||||
public Class getType(EvaluationContext ctx) throws ELException;
|
||||
|
||||
public boolean isReadOnly(EvaluationContext ctx) throws ELException;
|
||||
|
||||
public void accept(NodeVisitor visitor) throws Exception;
|
||||
|
||||
public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException;
|
||||
|
||||
public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException;
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
package org.apache.struts2.el.parser;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public interface NodeVisitor {
|
||||
public void visit(Node node) throws Exception;
|
||||
}
|
||||
@@ -1,226 +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.struts2.el.parser;
|
||||
|
||||
/**
|
||||
* This exception is thrown when parse errors are encountered.
|
||||
* You can explicitly create objects of this exception type by
|
||||
* calling the method generateParseException in the generated
|
||||
* parser.
|
||||
*
|
||||
* You can modify this class to customize your error reporting
|
||||
* mechanisms so long as you retain the public fields.
|
||||
*/
|
||||
public class ParseException extends Exception {
|
||||
|
||||
/**
|
||||
* This constructor is used by the method "generateParseException"
|
||||
* in the generated parser. Calling this constructor generates
|
||||
* a new object of this type with the fields "currentToken",
|
||||
* "expectedTokenSequences", and "tokenImage" set. The boolean
|
||||
* flag "specialConstructor" is also set to true to indicate that
|
||||
* this constructor was used to create this object.
|
||||
* This constructor calls its super class with the empty string
|
||||
* to force the "toString" method of parent class "Throwable" to
|
||||
* print the error message in the form:
|
||||
* ParseException: <result of getMessage>
|
||||
*
|
||||
* @param currentTokenVal current token value
|
||||
* @param expectedTokenSequencesVal expected token sequence value
|
||||
* @param tokenImageVal token image value
|
||||
*/
|
||||
public ParseException(Token currentTokenVal,
|
||||
int[][] expectedTokenSequencesVal,
|
||||
String[] tokenImageVal
|
||||
)
|
||||
{
|
||||
super("");
|
||||
specialConstructor = true;
|
||||
currentToken = currentTokenVal;
|
||||
expectedTokenSequences = expectedTokenSequencesVal;
|
||||
tokenImage = tokenImageVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following constructors are for use by you for whatever
|
||||
* purpose you can think of. Constructing the exception in this
|
||||
* manner makes the exception behave in the normal way - i.e., as
|
||||
* documented in the class "Throwable". The fields "errorToken",
|
||||
* "expectedTokenSequences", and "tokenImage" do not contain
|
||||
* relevant information. The JavaCC generated code does not use
|
||||
* these constructors.
|
||||
*/
|
||||
|
||||
public ParseException() {
|
||||
super();
|
||||
specialConstructor = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message.
|
||||
*
|
||||
* @param message exception message
|
||||
*/
|
||||
public ParseException(String message) {
|
||||
super(message);
|
||||
specialConstructor = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This variable determines which constructor was used to create
|
||||
* this object and thereby affects the semantics of the
|
||||
* "getMessage" method (see below).
|
||||
*/
|
||||
protected boolean specialConstructor;
|
||||
|
||||
/**
|
||||
* This is the last token that has been consumed successfully. If
|
||||
* this object has been created due to a parse error, the token
|
||||
* following this token will (therefore) be the first error token.
|
||||
*/
|
||||
public Token currentToken;
|
||||
|
||||
/**
|
||||
* Each entry in this array is an array of integers. Each array
|
||||
* of integers represents a sequence of tokens (by their ordinal
|
||||
* values) that is expected at this point of the parse.
|
||||
*/
|
||||
public int[][] expectedTokenSequences;
|
||||
|
||||
/**
|
||||
* This is a reference to the "tokenImage" array of the generated
|
||||
* parser within which the parse error occurred. This array is
|
||||
* defined in the generated ...Constants interface.
|
||||
*/
|
||||
public String[] tokenImage;
|
||||
|
||||
/**
|
||||
* This method has the standard behavior when this object has been
|
||||
* created using the standard constructors. Otherwise, it uses
|
||||
* "currentToken" and "expectedTokenSequences" to generate a parse
|
||||
* error message and returns it. If this object has been created
|
||||
* due to a parse error, and you do not catch it (it gets thrown
|
||||
* from the parser), then this method is called during the printing
|
||||
* of the final stack trace, and hence the correct error message
|
||||
* gets displayed.
|
||||
*
|
||||
* @return the exception message
|
||||
*/
|
||||
public String getMessage() {
|
||||
if (!specialConstructor) {
|
||||
return super.getMessage();
|
||||
}
|
||||
StringBuilder expected = new StringBuilder();
|
||||
int maxSize = 0;
|
||||
for (int[] expectedTokenSequence : expectedTokenSequences) {
|
||||
if (maxSize < expectedTokenSequence.length) {
|
||||
maxSize = expectedTokenSequence.length;
|
||||
}
|
||||
for (int anExpectedTokenSequence : expectedTokenSequence) {
|
||||
expected.append(tokenImage[anExpectedTokenSequence]).append(' ');
|
||||
}
|
||||
if (expectedTokenSequence[expectedTokenSequence.length - 1] != 0) {
|
||||
expected.append("...");
|
||||
}
|
||||
expected.append(eol).append(" ");
|
||||
}
|
||||
String retval = "Encountered \"";
|
||||
Token tok = currentToken.next;
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
if (i != 0) retval += " ";
|
||||
if (tok.kind == 0) {
|
||||
retval += tokenImage[0];
|
||||
break;
|
||||
}
|
||||
retval += " " + tokenImage[tok.kind];
|
||||
retval += " \"";
|
||||
retval += add_escapes(tok.image);
|
||||
retval += " \"";
|
||||
tok = tok.next;
|
||||
}
|
||||
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
|
||||
retval += "." + eol;
|
||||
if (expectedTokenSequences.length == 1) {
|
||||
retval += "Was expecting:" + eol + " ";
|
||||
} else {
|
||||
retval += "Was expecting one of:" + eol + " ";
|
||||
}
|
||||
retval += expected.toString();
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* The end of line string for this machine.
|
||||
*/
|
||||
protected String eol = System.getProperty("line.separator", "\n");
|
||||
|
||||
/**
|
||||
* Used to convert raw characters to their escaped version
|
||||
* when these raw version cannot be used as part of an ASCII
|
||||
* string literal.
|
||||
*
|
||||
* @param str string to escape
|
||||
* @return string with escapes
|
||||
*/
|
||||
protected String add_escapes(String str) {
|
||||
StringBuilder retval = new StringBuilder();
|
||||
char ch;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
switch (str.charAt(i))
|
||||
{
|
||||
case 0 :
|
||||
continue;
|
||||
case '\b':
|
||||
retval.append("\\b");
|
||||
continue;
|
||||
case '\t':
|
||||
retval.append("\\t");
|
||||
continue;
|
||||
case '\n':
|
||||
retval.append("\\n");
|
||||
continue;
|
||||
case '\f':
|
||||
retval.append("\\f");
|
||||
continue;
|
||||
case '\r':
|
||||
retval.append("\\r");
|
||||
continue;
|
||||
case '\"':
|
||||
retval.append("\\\"");
|
||||
continue;
|
||||
case '\'':
|
||||
retval.append("\\\'");
|
||||
continue;
|
||||
case '\\':
|
||||
retval.append("\\\\");
|
||||
continue;
|
||||
default:
|
||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
|
||||
String s = "0000" + Integer.toString(ch, 16);
|
||||
retval.append("\\u").append(s.substring(s.length() - 4, s.length()));
|
||||
} else {
|
||||
retval.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval.toString();
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=a147e4edaa2a39e08e6f250c30247549 (do not edit this line) */
|
||||
@@ -1,589 +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.struts2.el.parser;
|
||||
|
||||
/**
|
||||
* An implementation of interface CharStream, where the stream is assumed to
|
||||
* contain only ASCII characters (without unicode processing).
|
||||
*/
|
||||
|
||||
public class SimpleCharStream {
|
||||
/**
|
||||
* Whether parser is static.
|
||||
*/
|
||||
public static final boolean staticFlag = false;
|
||||
int bufsize;
|
||||
int available;
|
||||
int tokenBegin;
|
||||
/**
|
||||
* Position in buffer.
|
||||
*/
|
||||
public int bufpos = -1;
|
||||
protected int bufline[];
|
||||
protected int bufcolumn[];
|
||||
|
||||
protected int column = 0;
|
||||
protected int line = 1;
|
||||
|
||||
protected boolean prevCharIsCR = false;
|
||||
protected boolean prevCharIsLF = false;
|
||||
|
||||
protected java.io.Reader inputStream;
|
||||
|
||||
protected char[] buffer;
|
||||
protected int maxNextCharInd = 0;
|
||||
protected int inBuf = 0;
|
||||
protected int tabSize = 8;
|
||||
|
||||
protected void setTabSize(int i) {
|
||||
tabSize = i;
|
||||
}
|
||||
|
||||
protected int getTabSize(int i) {
|
||||
return tabSize;
|
||||
}
|
||||
|
||||
|
||||
protected void ExpandBuff(boolean wrapAround) {
|
||||
char[] newbuffer = new char[bufsize + 2048];
|
||||
int newbufline[] = new int[bufsize + 2048];
|
||||
int newbufcolumn[] = new int[bufsize + 2048];
|
||||
|
||||
try {
|
||||
if (wrapAround) {
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(buffer, 0, newbuffer,
|
||||
bufsize - tokenBegin, bufpos);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
|
||||
} else {
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos -= tokenBegin);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new Error(t.getMessage());
|
||||
}
|
||||
|
||||
|
||||
bufsize += 2048;
|
||||
available = bufsize;
|
||||
tokenBegin = 0;
|
||||
}
|
||||
|
||||
protected void FillBuff() throws java.io.IOException {
|
||||
if (maxNextCharInd == available) {
|
||||
if (available == bufsize) {
|
||||
if (tokenBegin > 2048) {
|
||||
bufpos = maxNextCharInd = 0;
|
||||
available = tokenBegin;
|
||||
} else if (tokenBegin < 0)
|
||||
bufpos = maxNextCharInd = 0;
|
||||
else
|
||||
ExpandBuff(false);
|
||||
} else if (available > tokenBegin)
|
||||
available = bufsize;
|
||||
else if ((tokenBegin - available) < 2048)
|
||||
ExpandBuff(true);
|
||||
else
|
||||
available = tokenBegin;
|
||||
}
|
||||
|
||||
int i;
|
||||
try {
|
||||
if ((i = inputStream.read(buffer, maxNextCharInd,
|
||||
available - maxNextCharInd)) == -1) {
|
||||
inputStream.close();
|
||||
throw new java.io.IOException();
|
||||
} else
|
||||
maxNextCharInd += i;
|
||||
return;
|
||||
} catch (java.io.IOException e) {
|
||||
--bufpos;
|
||||
backup(0);
|
||||
if (tokenBegin == -1)
|
||||
tokenBegin = bufpos;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start.
|
||||
*
|
||||
* @return first char
|
||||
* @throws java.io.IOException in case of IO errors
|
||||
*/
|
||||
public char BeginToken() throws java.io.IOException {
|
||||
tokenBegin = -1;
|
||||
char c = readChar();
|
||||
tokenBegin = bufpos;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
protected void UpdateLineColumn(char c) {
|
||||
column++;
|
||||
|
||||
if (prevCharIsLF) {
|
||||
prevCharIsLF = false;
|
||||
line += (column = 1);
|
||||
} else if (prevCharIsCR) {
|
||||
prevCharIsCR = false;
|
||||
if (c == '\n') {
|
||||
prevCharIsLF = true;
|
||||
} else
|
||||
line += (column = 1);
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case '\r':
|
||||
prevCharIsCR = true;
|
||||
break;
|
||||
case '\n':
|
||||
prevCharIsLF = true;
|
||||
break;
|
||||
case '\t':
|
||||
column--;
|
||||
column += (tabSize - (column % tabSize));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bufline[bufpos] = line;
|
||||
bufcolumn[bufpos] = column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a character.
|
||||
* @return character
|
||||
* @throws java.io.IOException in case of IO errors
|
||||
*/
|
||||
public char readChar() throws java.io.IOException {
|
||||
if (inBuf > 0) {
|
||||
--inBuf;
|
||||
|
||||
if (++bufpos == bufsize)
|
||||
bufpos = 0;
|
||||
|
||||
return buffer[bufpos];
|
||||
}
|
||||
|
||||
if (++bufpos >= maxNextCharInd)
|
||||
FillBuff();
|
||||
|
||||
char c = buffer[bufpos];
|
||||
|
||||
UpdateLineColumn(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return column
|
||||
* @see #getEndColumn
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
public int getColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return line
|
||||
* @see #getEndLine
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
public int getLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token end column number.
|
||||
*/
|
||||
public int getEndColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token end line number.
|
||||
*/
|
||||
public int getEndLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token beginning column number.
|
||||
*/
|
||||
public int getBeginColumn() {
|
||||
return bufcolumn[tokenBegin];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token beginning line number.
|
||||
*/
|
||||
public int getBeginLine() {
|
||||
return bufline[tokenBegin];
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup a number of characters.
|
||||
* @param amount amount of characters
|
||||
*/
|
||||
public void backup(int amount) {
|
||||
|
||||
inBuf += amount;
|
||||
if ((bufpos -= amount) < 0)
|
||||
bufpos += bufsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @param buffersize buffer size
|
||||
*/
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize) {
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
*/
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn) {
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
*/
|
||||
public SimpleCharStream(java.io.Reader dstream) {
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @param buffersize buffer size
|
||||
*/
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize) {
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
if (buffer == null || buffersize != buffer.length) {
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
prevCharIsLF = prevCharIsCR = false;
|
||||
tokenBegin = inBuf = maxNextCharInd = 0;
|
||||
bufpos = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
*/
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn) {
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
*/
|
||||
public void ReInit(java.io.Reader dstream) {
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param encoding encoding
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @param buffersize buffer size
|
||||
* @throws java.io.UnsupportedEncodingException in case of unsupported encoding
|
||||
*/
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException {
|
||||
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @param buffersize buffer size
|
||||
*/
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize) {
|
||||
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param encoding encoding
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @throws java.io.UnsupportedEncodingException in case of unsupported encoding
|
||||
*/
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn) throws java.io.UnsupportedEncodingException {
|
||||
this(dstream, encoding, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
*/
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn) {
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param encoding encoding
|
||||
* @throws java.io.UnsupportedEncodingException in case of unsupported encoding
|
||||
*/
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException {
|
||||
this(dstream, encoding, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param dstream stream
|
||||
*/
|
||||
public SimpleCharStream(java.io.InputStream dstream) {
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param encoding encoding
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @param buffersize buffer size
|
||||
* @throws java.io.UnsupportedEncodingException in case of unsupported encoding
|
||||
*/
|
||||
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException {
|
||||
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @param buffersize buffer size
|
||||
*/
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize) {
|
||||
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param encoding encoding
|
||||
* @throws java.io.UnsupportedEncodingException in case of unsupported encoding
|
||||
*/
|
||||
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException {
|
||||
ReInit(dstream, encoding, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
*/
|
||||
public void ReInit(java.io.InputStream dstream) {
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param encoding encoding
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
* @throws java.io.UnsupportedEncodingException in case of unsupported encoding
|
||||
*/
|
||||
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn) throws java.io.UnsupportedEncodingException {
|
||||
ReInit(dstream, encoding, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialise.
|
||||
*
|
||||
* @param dstream stream
|
||||
* @param startline start line
|
||||
* @param startcolumn start column
|
||||
*/
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn) {
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token literal value.
|
||||
*/
|
||||
public String GetImage() {
|
||||
if (bufpos >= tokenBegin)
|
||||
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
|
||||
else
|
||||
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
|
||||
new String(buffer, 0, bufpos + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param len length
|
||||
* @return the suffix.
|
||||
*/
|
||||
public char[] GetSuffix(int len) {
|
||||
char[] ret = new char[len];
|
||||
|
||||
if ((bufpos + 1) >= len)
|
||||
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
|
||||
else {
|
||||
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
|
||||
len - bufpos - 1);
|
||||
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset buffer when finished.
|
||||
*/
|
||||
public void Done() {
|
||||
buffer = null;
|
||||
bufline = null;
|
||||
bufcolumn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to adjust line and column numbers for the start of a token.
|
||||
* @param newLine new line
|
||||
* @param newCol new column
|
||||
*/
|
||||
public void adjustBeginLineColumn(int newLine, int newCol) {
|
||||
int start = tokenBegin;
|
||||
int len;
|
||||
|
||||
if (bufpos >= tokenBegin) {
|
||||
len = bufpos - tokenBegin + inBuf + 1;
|
||||
} else {
|
||||
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
|
||||
}
|
||||
|
||||
int i = 0, j = 0, k = 0;
|
||||
int nextColDiff = 0, columnDiff = 0;
|
||||
|
||||
while (i < len &&
|
||||
bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
|
||||
bufline[j] = newLine;
|
||||
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
columnDiff = nextColDiff;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < len) {
|
||||
bufline[j] = newLine++;
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
|
||||
while (i++ < len) {
|
||||
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
|
||||
bufline[j] = newLine++;
|
||||
else
|
||||
bufline[j] = newLine;
|
||||
}
|
||||
}
|
||||
|
||||
line = bufline[j];
|
||||
column = bufcolumn[j];
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=07e88967db3720fcfc378bbb17e7f640 (do not edit this line) */
|
||||
@@ -1,159 +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.struts2.el.parser;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.MethodInfo;
|
||||
import jakarta.el.PropertyNotWritableException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELSupport;
|
||||
import org.apache.struts2.el.lang.EvaluationContext;
|
||||
import org.apache.struts2.el.util.MessageFactory;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public abstract class SimpleNode extends ELSupport implements Node {
|
||||
protected Node parent;
|
||||
|
||||
protected Node[] children;
|
||||
|
||||
protected int id;
|
||||
|
||||
protected String image;
|
||||
|
||||
public SimpleNode(int i) {
|
||||
id = i;
|
||||
}
|
||||
|
||||
public void jjtOpen() {
|
||||
}
|
||||
|
||||
public void jjtClose() {
|
||||
}
|
||||
|
||||
public void jjtSetParent(Node n) {
|
||||
parent = n;
|
||||
}
|
||||
|
||||
public Node jjtGetParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void jjtAddChild(Node n, int i) {
|
||||
if (children == null) {
|
||||
children = new Node[i + 1];
|
||||
} else if (i >= children.length) {
|
||||
Node c[] = new Node[i + 1];
|
||||
System.arraycopy(children, 0, c, 0, children.length);
|
||||
children = c;
|
||||
}
|
||||
children[i] = n;
|
||||
}
|
||||
|
||||
public Node jjtGetChild(int i) {
|
||||
return children[i];
|
||||
}
|
||||
|
||||
public int jjtGetNumChildren() {
|
||||
return (children == null) ? 0 : children.length;
|
||||
}
|
||||
|
||||
/*
|
||||
* You can override these two methods in subclasses of SimpleNode to
|
||||
* customize the way the node appears when the tree is dumped. If your
|
||||
* output uses more than one line you should override toString(String),
|
||||
* otherwise overriding toString() is probably all you need to do.
|
||||
*/
|
||||
|
||||
public String toString() {
|
||||
if (this.image != null) {
|
||||
return ELParserTreeConstants.jjtNodeName[id] + "[" + this.image
|
||||
+ "]";
|
||||
}
|
||||
return ELParserTreeConstants.jjtNodeName[id];
|
||||
}
|
||||
|
||||
public String toString(String prefix) {
|
||||
return prefix + toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Override this method if you want to customize how the node dumps out its
|
||||
* children.
|
||||
*/
|
||||
|
||||
public void dump(String prefix) {
|
||||
System.out.println(toString(prefix));
|
||||
if (children != null) {
|
||||
for (int i = 0; i < children.length; ++i) {
|
||||
SimpleNode n = (SimpleNode) children[i];
|
||||
if (n != null) {
|
||||
n.dump(prefix + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public Class getType(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Object getValue(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean isReadOnly(EvaluationContext ctx)
|
||||
throws ELException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValue(EvaluationContext ctx, Object value)
|
||||
throws ELException {
|
||||
throw new PropertyNotWritableException(MessageFactory.get("error.syntax.set"));
|
||||
}
|
||||
|
||||
public void accept(NodeVisitor visitor) throws Exception {
|
||||
visitor.visit(this);
|
||||
if (this.children != null && this.children.length > 0) {
|
||||
for (int i = 0; i < this.children.length; i++) {
|
||||
this.children[i].accept(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -1,152 +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.struts2.el.parser;
|
||||
|
||||
/**
|
||||
* Describes the input token stream.
|
||||
*/
|
||||
|
||||
public class Token {
|
||||
|
||||
/**
|
||||
* An integer that describes the kind of this token. This numbering
|
||||
* system is determined by JavaCCParser, and a table of these numbers is
|
||||
* stored in the file ...Constants.java.
|
||||
*/
|
||||
public int kind;
|
||||
|
||||
/** The line number of the first character of this Token. */
|
||||
public int beginLine;
|
||||
/** The column number of the first character of this Token. */
|
||||
public int beginColumn;
|
||||
/** The line number of the last character of this Token. */
|
||||
public int endLine;
|
||||
/** The column number of the last character of this Token. */
|
||||
public int endColumn;
|
||||
|
||||
/**
|
||||
* The string image of the token.
|
||||
*/
|
||||
public String image;
|
||||
|
||||
/**
|
||||
* A reference to the next regular (non-special) token from the input
|
||||
* stream. If this is the last token from the input stream, or if the
|
||||
* token manager has not read tokens beyond this one, this field is
|
||||
* set to null. This is true only if this token is also a regular
|
||||
* token. Otherwise, see below for a description of the contents of
|
||||
* this field.
|
||||
*/
|
||||
public Token next;
|
||||
|
||||
/**
|
||||
* This field is used to access special tokens that occur prior to this
|
||||
* token, but after the immediately preceding regular (non-special) token.
|
||||
* If there are no such special tokens, this field is set to null.
|
||||
* When there are more than one such special token, this field refers
|
||||
* to the last of these special tokens, which in turn refers to the next
|
||||
* previous special token through its specialToken field, and so on
|
||||
* until the first special token (whose specialToken field is null).
|
||||
* The next fields of special tokens refer to other special tokens that
|
||||
* immediately follow it (without an intervening regular token). If there
|
||||
* is no such token, this field is null.
|
||||
*/
|
||||
public Token specialToken;
|
||||
|
||||
/**
|
||||
* An optional attribute value of the Token.
|
||||
* Tokens which are not used as syntactic sugar will often contain
|
||||
* meaningful values that will be used later on by the compiler or
|
||||
* interpreter. This attribute value is often different from the image.
|
||||
* Any subclass of Token that actually wants to return a non-null value can
|
||||
* override this method as appropriate.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* No-argument constructor
|
||||
*/
|
||||
public Token() {}
|
||||
|
||||
/**
|
||||
* Constructs a new token for the specified Image.
|
||||
*
|
||||
* @param kind kind
|
||||
*/
|
||||
public Token(int kind)
|
||||
{
|
||||
this(kind, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new token for the specified Image and Kind.
|
||||
*
|
||||
* @param kind kind
|
||||
* @param image image
|
||||
*/
|
||||
public Token(int kind, String image)
|
||||
{
|
||||
this.kind = kind;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the image.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Token object, by default. However, if you want, you
|
||||
* can create and return subclass objects based on the value of ofKind.
|
||||
* Simply add the cases to the switch for all those special cases.
|
||||
* For example, if you have a subclass of Token called IDToken that
|
||||
* you want to create if ofKind is ID, simply add something like :
|
||||
*
|
||||
* case MyParserConstants.ID : return new IDToken(ofKind, image);
|
||||
*
|
||||
* to the following switch statement. Then you can cast matchedToken
|
||||
* variable to the appropriate type and use sit in your lexical actions.
|
||||
*
|
||||
* @param ofKind ofKind
|
||||
* @param image image
|
||||
*
|
||||
* @return new token
|
||||
*/
|
||||
public static Token newToken(int ofKind, String image)
|
||||
{
|
||||
switch(ofKind)
|
||||
{
|
||||
default : return new Token(ofKind, image);
|
||||
}
|
||||
}
|
||||
|
||||
public static Token newToken(int ofKind)
|
||||
{
|
||||
return newToken(ofKind, null);
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=384f0c8d72f06824f8ad2f5b33eb5e59 (do not edit this line) */
|
||||
@@ -1,175 +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.struts2.el.parser;
|
||||
|
||||
/** Token Manager Error. */
|
||||
public class TokenMgrError extends Error
|
||||
{
|
||||
|
||||
/*
|
||||
* Ordinals for various reasons why an Error of this type can be thrown.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lexical error occurred.
|
||||
*/
|
||||
static final int LEXICAL_ERROR = 0;
|
||||
|
||||
/**
|
||||
* An attempt was made to create a second instance of a static token manager.
|
||||
*/
|
||||
static final int STATIC_LEXER_ERROR = 1;
|
||||
|
||||
/**
|
||||
* Tried to change to an invalid lexical state.
|
||||
*/
|
||||
static final int INVALID_LEXICAL_STATE = 2;
|
||||
|
||||
/**
|
||||
* Detected (and bailed out of) an infinite loop in the token manager.
|
||||
*/
|
||||
static final int LOOP_DETECTED = 3;
|
||||
|
||||
/**
|
||||
* Indicates the reason why the exception is thrown. It will have
|
||||
* one of the above 4 values.
|
||||
*/
|
||||
int errorCode;
|
||||
|
||||
/**
|
||||
* Replaces unprintable characters by their escaped (or unicode escaped)
|
||||
* equivalents in the given string
|
||||
*
|
||||
* @param str string
|
||||
* @return escaped string
|
||||
*/
|
||||
protected static final String addEscapes(String str) {
|
||||
StringBuilder retval = new StringBuilder();
|
||||
char ch;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
switch (str.charAt(i))
|
||||
{
|
||||
case 0 :
|
||||
continue;
|
||||
case '\b':
|
||||
retval.append("\\b");
|
||||
continue;
|
||||
case '\t':
|
||||
retval.append("\\t");
|
||||
continue;
|
||||
case '\n':
|
||||
retval.append("\\n");
|
||||
continue;
|
||||
case '\f':
|
||||
retval.append("\\f");
|
||||
continue;
|
||||
case '\r':
|
||||
retval.append("\\r");
|
||||
continue;
|
||||
case '\"':
|
||||
retval.append("\\\"");
|
||||
continue;
|
||||
case '\'':
|
||||
retval.append("\\\'");
|
||||
continue;
|
||||
case '\\':
|
||||
retval.append("\\\\");
|
||||
continue;
|
||||
default:
|
||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
|
||||
String s = "0000" + Integer.toString(ch, 16);
|
||||
retval.append("\\u").append(s.substring(s.length() - 4, s.length()));
|
||||
} else {
|
||||
retval.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: You can customize the lexical error message by modifying this method.
|
||||
*
|
||||
* @param EOFSeen : indicates if EOF caused the lexical error
|
||||
* @param lexState : lexical state in which this error occurred
|
||||
* @param errorLine : line number when the error occurred
|
||||
* @param errorColumn : column number when the error occurred
|
||||
* @param errorAfter : prefix that was seen before this error occurred
|
||||
* @param curChar : the offending character
|
||||
*
|
||||
* @return a detailed message for the Error when it is thrown by the token manager to indicate a lexical error.
|
||||
*/
|
||||
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
|
||||
return("Lexical error at line " +
|
||||
errorLine + ", column " +
|
||||
errorColumn + ". Encountered: " +
|
||||
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
|
||||
"after : \"" + addEscapes(errorAfter) + "\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* You can also modify the body of this method to customize your error messages.
|
||||
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
|
||||
* of end-users concern, so you can return something like :
|
||||
*
|
||||
* "Internal Error : Please file a bug report .... "
|
||||
*
|
||||
* from this method for such cases in the release version of your parser.
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructors of various flavors follow.
|
||||
*/
|
||||
|
||||
/** No arg constructor. */
|
||||
public TokenMgrError() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message and reason.
|
||||
*
|
||||
* @param message the error message
|
||||
* @param reason the reason
|
||||
*/
|
||||
public TokenMgrError(String message, int reason) {
|
||||
super(message);
|
||||
errorCode = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full Constructor.
|
||||
*
|
||||
* @param EOFSeen indicates if EOF caused the lexical error
|
||||
* @param lexState lexical state in which this error occurred
|
||||
* @param errorLine line number when the error occurred
|
||||
* @param errorColumn column number when the error occurred
|
||||
* @param errorAfter prefix that was seen before this error occurred
|
||||
* @param curChar the offending character
|
||||
* @param reason the reason
|
||||
*/
|
||||
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
|
||||
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
|
||||
}
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=8048f4b229a762baa426e8e8436dbe9e (do not edit this line) */
|
||||
@@ -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.struts2.el.util;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public final class ConcurrentCache<K,V> {
|
||||
|
||||
private final int size;
|
||||
|
||||
private final Map<K,V> eden;
|
||||
|
||||
private final Map<K,V> longterm;
|
||||
|
||||
public ConcurrentCache(int size) {
|
||||
this.size = size;
|
||||
this.eden = new ConcurrentHashMap<K,V>(size);
|
||||
this.longterm = new WeakHashMap<K,V>(size);
|
||||
}
|
||||
|
||||
public V get(K k) {
|
||||
V v = this.eden.get(k);
|
||||
if (v == null) {
|
||||
v = this.longterm.get(k);
|
||||
if (v != null) {
|
||||
this.eden.put(k, v);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public void put(K k, V v) {
|
||||
if (this.eden.size() >= size) {
|
||||
this.longterm.putAll(this.eden);
|
||||
this.eden.clear();
|
||||
}
|
||||
this.eden.put(k, v);
|
||||
}
|
||||
}
|
||||
@@ -1,72 +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.struts2.el.util;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: rjung $
|
||||
*/
|
||||
public final class MessageFactory {
|
||||
|
||||
protected final static ResourceBundle bundle = ResourceBundle
|
||||
.getBundle("org.apache.el.Messages");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public MessageFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static String get(final String key) {
|
||||
return bundle.getString(key);
|
||||
}
|
||||
|
||||
public static String get(final String key, final Object obj0) {
|
||||
return getArray(key, new Object[] { obj0 });
|
||||
}
|
||||
|
||||
public static String get(final String key, final Object obj0,
|
||||
final Object obj1) {
|
||||
return getArray(key, new Object[] { obj0, obj1 });
|
||||
}
|
||||
|
||||
public static String get(final String key, final Object obj0,
|
||||
final Object obj1, final Object obj2) {
|
||||
return getArray(key, new Object[] { obj0, obj1, obj2 });
|
||||
}
|
||||
|
||||
public static String get(final String key, final Object obj0,
|
||||
final Object obj1, final Object obj2, final Object obj3) {
|
||||
return getArray(key, new Object[] { obj0, obj1, obj2, obj3 });
|
||||
}
|
||||
|
||||
public static String get(final String key, final Object obj0,
|
||||
final Object obj1, final Object obj2, final Object obj3,
|
||||
final Object obj4) {
|
||||
return getArray(key, new Object[] { obj0, obj1, obj2, obj3, obj4 });
|
||||
}
|
||||
|
||||
public static String getArray(final String key, final Object[] objA) {
|
||||
return MessageFormat.format(bundle.getString(key), objA);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,182 +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.struts2.el.util;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import jakarta.el.ELException;
|
||||
import jakarta.el.MethodNotFoundException;
|
||||
import jakarta.el.PropertyNotFoundException;
|
||||
|
||||
import org.apache.struts2.el.lang.ELSupport;
|
||||
|
||||
/**
|
||||
* Utilities for Managing Serialization and Reflection
|
||||
*
|
||||
* @author Jacob Hookom [jacob@hookom.net]
|
||||
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
|
||||
*/
|
||||
public class ReflectionUtil {
|
||||
|
||||
protected static final String[] EMPTY_STRING = new String[0];
|
||||
|
||||
protected static final String[] PRIMITIVE_NAMES = new String[] { "boolean",
|
||||
"byte", "char", "double", "float", "int", "long", "short", "void" };
|
||||
|
||||
protected static final Class[] PRIMITIVES = new Class[] { boolean.class,
|
||||
byte.class, char.class, double.class, float.class, int.class,
|
||||
long.class, short.class, Void.TYPE };
|
||||
|
||||
private ReflectionUtil() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static Class forName(String name) throws ClassNotFoundException {
|
||||
if (null == name || "".equals(name)) {
|
||||
return null;
|
||||
}
|
||||
Class c = forNamePrimitive(name);
|
||||
if (c == null) {
|
||||
if (name.endsWith("[]")) {
|
||||
String nc = name.substring(0, name.length() - 2);
|
||||
c = Class.forName(nc, true, Thread.currentThread().getContextClassLoader());
|
||||
c = Array.newInstance(c, 0).getClass();
|
||||
} else {
|
||||
c = Class.forName(name, true, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
protected static Class forNamePrimitive(String name) {
|
||||
if (name.length() <= 8) {
|
||||
int p = Arrays.binarySearch(PRIMITIVE_NAMES, name);
|
||||
if (p >= 0) {
|
||||
return PRIMITIVES[p];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of Class names to Class types
|
||||
* @param s array of class names
|
||||
* @return array of class types
|
||||
* @throws ClassNotFoundException if class was not found
|
||||
*/
|
||||
public static Class[] toTypeArray(String[] s) throws ClassNotFoundException {
|
||||
if (s == null)
|
||||
return null;
|
||||
Class[] c = new Class[s.length];
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
c[i] = forName(s[i]);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of Class types to Class names
|
||||
* @param c array of class types
|
||||
* @return array of class names
|
||||
*/
|
||||
public static String[] toTypeNameArray(Class[] c) {
|
||||
if (c == null)
|
||||
return null;
|
||||
String[] s = new String[c.length];
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
s[i] = c[i].getName();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a method based on the criteria
|
||||
* @param base the object that owns the method
|
||||
* @param property the name of the method
|
||||
* @param paramTypes the parameter types to use
|
||||
* @return the method specified
|
||||
* @throws MethodNotFoundException if method was not found
|
||||
*/
|
||||
public static Method getMethod(Object base, Object property,
|
||||
Class[] paramTypes) throws MethodNotFoundException {
|
||||
if (base == null || property == null) {
|
||||
throw new MethodNotFoundException(MessageFactory.get(
|
||||
"error.method.notfound", base, property,
|
||||
paramString(paramTypes)));
|
||||
}
|
||||
|
||||
String methodName = (property instanceof String) ? (String) property
|
||||
: property.toString();
|
||||
|
||||
Method method = null;
|
||||
try {
|
||||
method = base.getClass().getMethod(methodName, paramTypes);
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
throw new MethodNotFoundException(MessageFactory.get(
|
||||
"error.method.notfound", base, property,
|
||||
paramString(paramTypes)));
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
protected static final String paramString(Class[] types) {
|
||||
if (types != null) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
sb.append(types[i].getName()).append(", ");
|
||||
}
|
||||
if (sb.length() > 2) {
|
||||
sb.setLength(sb.length() - 2);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param base object
|
||||
* @param property property
|
||||
* @return property descriptor
|
||||
* @throws ELException in case of EL errors
|
||||
* @throws PropertyNotFoundException if property was not found
|
||||
*/
|
||||
public static PropertyDescriptor getPropertyDescriptor(Object base,
|
||||
Object property) throws ELException, PropertyNotFoundException {
|
||||
String name = ELSupport.coerceToString(property);
|
||||
PropertyDescriptor p = null;
|
||||
try {
|
||||
PropertyDescriptor[] desc = Introspector.getBeanInfo(
|
||||
base.getClass()).getPropertyDescriptors();
|
||||
for (int i = 0; i < desc.length; i++) {
|
||||
if (desc[i].getName().equals(name)) {
|
||||
return desc[i];
|
||||
}
|
||||
}
|
||||
} catch (IntrospectionException ie) {
|
||||
throw new ELException(ie);
|
||||
}
|
||||
throw new PropertyNotFoundException(MessageFactory.get(
|
||||
"error.property.notfound", base, name));
|
||||
}
|
||||
}
|
||||
@@ -1,208 +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.struts2.jasper;
|
||||
|
||||
/**
|
||||
* Some constants and other global data that are used by the compiler and the runtime.
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
* @author Harish Prabandham
|
||||
* @author Shawn Bayern
|
||||
* @author Mark Roth
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
/**
|
||||
* The base class of the generated servlets.
|
||||
*/
|
||||
public static final String JSP_SERVLET_BASE =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.JSP_SERVLET_BASE", "org.apache.struts2.jasper.runtime.HttpJspBase");
|
||||
|
||||
/**
|
||||
* _jspService is the name of the method that is called by
|
||||
* HttpJspBase.service(). This is where most of the code generated
|
||||
* from JSPs go.
|
||||
*/
|
||||
public static final String SERVICE_METHOD_NAME =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.SERVICE_METHOD_NAME", "_jspService");
|
||||
|
||||
/**
|
||||
* Default servlet content type.
|
||||
*/
|
||||
public static final String SERVLET_CONTENT_TYPE = "text/html";
|
||||
|
||||
/**
|
||||
* These classes/packages are automatically imported by the
|
||||
* generated code.
|
||||
*/
|
||||
public static final String[] STANDARD_IMPORTS = {
|
||||
"jakarta.servlet.*",
|
||||
"jakarta.servlet.http.*",
|
||||
"jakarta.servlet.jsp.*"
|
||||
};
|
||||
|
||||
/**
|
||||
* ServletContext attribute for classpath. This is tomcat specific.
|
||||
* Other servlet engines may choose to support this attribute if they
|
||||
* want to have this JSP engine running on them.
|
||||
*/
|
||||
public static final String SERVLET_CLASSPATH =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.SERVLET_CLASSPATH", "org.apache.catalina.jsp_classpath");
|
||||
|
||||
/**
|
||||
* Request attribute for <code><jsp-file></code> element of a
|
||||
* servlet definition. If present on a request, this overrides the
|
||||
* value returned by <code>request.getServletPath()</code> to select
|
||||
* the JSP page to be executed.
|
||||
*/
|
||||
public static final String JSP_FILE =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.JSP_FILE", "org.apache.catalina.jsp_file");
|
||||
|
||||
|
||||
/**
|
||||
* Default size of the JSP buffer.
|
||||
*/
|
||||
public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
/**
|
||||
* Default size for the tag buffers.
|
||||
*/
|
||||
public static final int DEFAULT_TAG_BUFFER_SIZE = 512;
|
||||
|
||||
/**
|
||||
* Default tag handler pool size.
|
||||
*/
|
||||
public static final int MAX_POOL_SIZE = 5;
|
||||
|
||||
/**
|
||||
* The query parameter that causes the JSP engine to just
|
||||
* pregenerated the servlet but not invoke it.
|
||||
*/
|
||||
public static final String PRECOMPILE =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.PRECOMPILE", "jsp_precompile");
|
||||
|
||||
/**
|
||||
* The default package name for compiled jsp pages.
|
||||
*/
|
||||
public static final String JSP_PACKAGE_NAME =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.JSP_PACKAGE_NAME", "org.apache.jsp");
|
||||
|
||||
/**
|
||||
* The default package name for tag handlers generated from tag files
|
||||
*/
|
||||
public static final String TAG_FILE_PACKAGE_NAME =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.TAG_FILE_PACKAGE_NAME", "org.apache.jsp.tag");
|
||||
|
||||
/**
|
||||
* Servlet context and request attributes that the JSP engine
|
||||
* uses.
|
||||
*/
|
||||
public static final String INC_SERVLET_PATH = "jakarta.servlet.include.servlet_path";
|
||||
public static final String TMP_DIR = "jakarta.servlet.context.tempdir";
|
||||
|
||||
// Must be kept in sync with org/apache/catalina/Globals.java
|
||||
public static final String ALT_DD_ATTR =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.ALT_DD_ATTR", "org.apache.catalina.deploy.alt_dd");
|
||||
|
||||
/**
|
||||
* Public Id and the Resource path (of the cached copy)
|
||||
* of the DTDs for tag library descriptors.
|
||||
*/
|
||||
public static final String TAGLIB_DTD_PUBLIC_ID_11 =
|
||||
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN";
|
||||
public static final String TAGLIB_DTD_RESOURCE_PATH_11 =
|
||||
"/javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd";
|
||||
public static final String TAGLIB_DTD_PUBLIC_ID_12 =
|
||||
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN";
|
||||
public static final String TAGLIB_DTD_RESOURCE_PATH_12 =
|
||||
"/javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd";
|
||||
|
||||
/**
|
||||
* Public Id and the Resource path (of the cached copy)
|
||||
* of the DTDs for web application deployment descriptors
|
||||
*/
|
||||
public static final String WEBAPP_DTD_PUBLIC_ID_22 =
|
||||
"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN";
|
||||
public static final String WEBAPP_DTD_RESOURCE_PATH_22 =
|
||||
"/javax/servlet/resources/web-app_2_2.dtd";
|
||||
public static final String WEBAPP_DTD_PUBLIC_ID_23 =
|
||||
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN";
|
||||
public static final String WEBAPP_DTD_RESOURCE_PATH_23 =
|
||||
"/javax/servlet/resources/web-app_2_3.dtd";
|
||||
|
||||
/**
|
||||
* List of the Public IDs that we cache, and their
|
||||
* associated location. This is used by
|
||||
* an EntityResolver to return the location of the
|
||||
* cached copy of a DTD.
|
||||
*/
|
||||
public static final String[] CACHED_DTD_PUBLIC_IDS = {
|
||||
TAGLIB_DTD_PUBLIC_ID_11,
|
||||
TAGLIB_DTD_PUBLIC_ID_12,
|
||||
WEBAPP_DTD_PUBLIC_ID_22,
|
||||
WEBAPP_DTD_PUBLIC_ID_23,
|
||||
};
|
||||
public static final String[] CACHED_DTD_RESOURCE_PATHS = {
|
||||
TAGLIB_DTD_RESOURCE_PATH_11,
|
||||
TAGLIB_DTD_RESOURCE_PATH_12,
|
||||
WEBAPP_DTD_RESOURCE_PATH_22,
|
||||
WEBAPP_DTD_RESOURCE_PATH_23,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default URLs to download the pluging for Netscape and IE.
|
||||
*/
|
||||
public static final String NS_PLUGIN_URL =
|
||||
"http://java.sun.com/products/plugin/";
|
||||
|
||||
public static final String IE_PLUGIN_URL =
|
||||
"http://java.sun.com/products/plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0";
|
||||
|
||||
/**
|
||||
* Prefix to use for generated temporary variable names
|
||||
*/
|
||||
public static final String TEMP_VARIABLE_NAME_PREFIX =
|
||||
System.getProperty("org.apache.struts2.jasper.Constants.TEMP_VARIABLE_NAME_PREFIX", "_jspx_temp");
|
||||
|
||||
/**
|
||||
* A replacement char for "\$".
|
||||
* XXX This is a hack to avoid changing EL interpreter to recognize "\$"
|
||||
* @deprecated
|
||||
*/
|
||||
public static final char ESC = '\u001b';
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static final String ESCStr = "'\\u001b'";
|
||||
|
||||
/**
|
||||
* Has security been turned on?
|
||||
*/
|
||||
public static final boolean IS_SECURITY_ENABLED =
|
||||
(System.getSecurityManager() != null);
|
||||
|
||||
/**
|
||||
* The name of the path parameter used to pass the session identifier
|
||||
* back and forth with the client.
|
||||
*/
|
||||
public static final String SESSION_PARAMETER_NAME =
|
||||
System.getProperty("org.apache.catalina.SESSION_PARAMETER_NAME",
|
||||
"jsessionid");
|
||||
|
||||
}
|
||||
@@ -1,35 +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.struts2.jasper;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
public class CustomCompiler extends org.apache.struts2.jasper.compiler.Compiler {
|
||||
|
||||
public boolean isOutDated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isOutDated(boolean checkClass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void generateClass(String[] smap) throws FileNotFoundException, JasperException, Exception {
|
||||
}
|
||||
}
|
||||
-668
@@ -1,668 +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.struts2.jasper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import jakarta.servlet.ServletConfig;
|
||||
import jakarta.servlet.ServletContext;
|
||||
|
||||
import org.apache.struts2.jasper.compiler.TldLocationsCache;
|
||||
import org.apache.struts2.jasper.compiler.JspConfig;
|
||||
import org.apache.struts2.jasper.compiler.TagPluginManager;
|
||||
import org.apache.struts2.jasper.compiler.Localizer;
|
||||
import org.apache.struts2.jasper.xmlparser.ParserUtils;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A class to hold all init parameters specific to the JSP engine.
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
* @author Hans Bergsten
|
||||
* @author Pierre Delisle
|
||||
*/
|
||||
public final class EmbeddedServletOptions implements Options {
|
||||
|
||||
// Logger
|
||||
private Log log = LogFactory.getLog(EmbeddedServletOptions.class);
|
||||
|
||||
private Properties settings = new Properties();
|
||||
|
||||
/**
|
||||
* Is Jasper being used in development mode?
|
||||
*/
|
||||
private boolean development = true;
|
||||
|
||||
/**
|
||||
* Should Ant fork its java compiles of JSP pages.
|
||||
*/
|
||||
public boolean fork = true;
|
||||
|
||||
/**
|
||||
* Do you want to keep the generated Java files around?
|
||||
*/
|
||||
private boolean keepGenerated = true;
|
||||
|
||||
/**
|
||||
* Should white spaces between directives or actions be trimmed?
|
||||
*/
|
||||
private boolean trimSpaces = false;
|
||||
|
||||
/**
|
||||
* Determines whether tag handler pooling is enabled.
|
||||
*/
|
||||
private boolean isPoolingEnabled = true;
|
||||
|
||||
/**
|
||||
* Do you want support for "mapped" files? This will generate
|
||||
* servlet that has a print statement per line of the JSP file.
|
||||
* This seems like a really nice feature to have for debugging.
|
||||
*/
|
||||
private boolean mappedFile = true;
|
||||
|
||||
/**
|
||||
* Do we want to include debugging information in the class file?
|
||||
*/
|
||||
private boolean classDebugInfo = true;
|
||||
|
||||
/**
|
||||
* Background compile thread check interval in seconds.
|
||||
*/
|
||||
private int checkInterval = 0;
|
||||
|
||||
/**
|
||||
* Is the generation of SMAP info for JSR45 debuggin suppressed?
|
||||
*/
|
||||
private boolean isSmapSuppressed = false;
|
||||
|
||||
/**
|
||||
* Should SMAP info for JSR45 debugging be dumped to a file?
|
||||
*/
|
||||
private boolean isSmapDumped = false;
|
||||
|
||||
/**
|
||||
* Are Text strings to be generated as char arrays?
|
||||
*/
|
||||
private boolean genStringAsCharArray = false;
|
||||
|
||||
private boolean errorOnUseBeanInvalidClassAttribute = true;
|
||||
|
||||
/**
|
||||
* I want to see my generated servlets. Which directory are they
|
||||
* in?
|
||||
*/
|
||||
private File scratchDir;
|
||||
|
||||
/**
|
||||
* Need to have this as is for versions 4 and 5 of IE. Can be set from
|
||||
* the initParams so if it changes in the future all that is needed is
|
||||
* to have a jsp initParam of type ieClassId="<value>"
|
||||
*/
|
||||
private String ieClassId = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
|
||||
|
||||
/**
|
||||
* What classpath should I use while compiling generated servlets?
|
||||
*/
|
||||
private String classpath = null;
|
||||
|
||||
/**
|
||||
* Compiler to use.
|
||||
*/
|
||||
private String compiler = null;
|
||||
|
||||
/**
|
||||
* Compiler target VM.
|
||||
*/
|
||||
private String compilerTargetVM = "1.5";
|
||||
|
||||
/**
|
||||
* The compiler source VM.
|
||||
*/
|
||||
private String compilerSourceVM = "1.5";
|
||||
|
||||
/**
|
||||
* The compiler class name.
|
||||
*/
|
||||
private String compilerClassName = null;
|
||||
|
||||
/**
|
||||
* Cache for the TLD locations
|
||||
*/
|
||||
private TldLocationsCache tldLocationsCache = null;
|
||||
|
||||
/**
|
||||
* Jsp config information
|
||||
*/
|
||||
private JspConfig jspConfig = null;
|
||||
|
||||
/**
|
||||
* TagPluginManager
|
||||
*/
|
||||
private TagPluginManager tagPluginManager = null;
|
||||
|
||||
/**
|
||||
* Java platform encoding to generate the JSP
|
||||
* page servlet.
|
||||
*/
|
||||
private String javaEncoding = "UTF8";
|
||||
|
||||
/**
|
||||
* Modification test interval.
|
||||
*/
|
||||
private int modificationTestInterval = 4;
|
||||
|
||||
/**
|
||||
* Is generation of X-Powered-By response header enabled/disabled?
|
||||
*/
|
||||
private boolean xpoweredBy;
|
||||
|
||||
/**
|
||||
* Should we include a source fragment in exception messages, which could be displayed
|
||||
* to the developer ?
|
||||
*/
|
||||
private boolean displaySourceFragment = true;
|
||||
|
||||
|
||||
public String getProperty(String name ) {
|
||||
return settings.getProperty( name );
|
||||
}
|
||||
|
||||
public void setProperty(String name, String value ) {
|
||||
if (name != null && value != null){
|
||||
settings.setProperty( name, value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we keeping generated code around?
|
||||
*/
|
||||
public boolean getKeepGenerated() {
|
||||
return keepGenerated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should white spaces between directives or actions be trimmed?
|
||||
*/
|
||||
public boolean getTrimSpaces() {
|
||||
return trimSpaces;
|
||||
}
|
||||
|
||||
public boolean isPoolingEnabled() {
|
||||
return isPoolingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we supporting HTML mapped servlets?
|
||||
*/
|
||||
public boolean getMappedFile() {
|
||||
return mappedFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class files be compiled with debug information?
|
||||
*/
|
||||
public boolean getClassDebugInfo() {
|
||||
return classDebugInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background JSP compile thread check intervall
|
||||
*/
|
||||
public int getCheckInterval() {
|
||||
return checkInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modification test interval.
|
||||
*/
|
||||
public int getModificationTestInterval() {
|
||||
return modificationTestInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Jasper being used in development mode?
|
||||
*/
|
||||
public boolean getDevelopment() {
|
||||
return development;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the generation of SMAP info for JSR45 debuggin suppressed?
|
||||
*/
|
||||
public boolean isSmapSuppressed() {
|
||||
return isSmapSuppressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should SMAP info for JSR45 debugging be dumped to a file?
|
||||
*/
|
||||
public boolean isSmapDumped() {
|
||||
return isSmapDumped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are Text strings to be generated as char arrays?
|
||||
*/
|
||||
public boolean genStringAsCharArray() {
|
||||
return this.genStringAsCharArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ID for use in the plugin tag when the browser is IE.
|
||||
*/
|
||||
public String getIeClassId() {
|
||||
return ieClassId;
|
||||
}
|
||||
|
||||
/**
|
||||
* What is my scratch dir?
|
||||
*/
|
||||
public File getScratchDir() {
|
||||
return scratchDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* What classpath should I use while compiling the servlets
|
||||
* generated from JSP files?
|
||||
*/
|
||||
public String getClassPath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is generation of X-Powered-By response header enabled/disabled?
|
||||
*/
|
||||
public boolean isXpoweredBy() {
|
||||
return xpoweredBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiler to use.
|
||||
*/
|
||||
public String getCompiler() {
|
||||
return compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Options#getCompilerTargetVM
|
||||
*/
|
||||
public String getCompilerTargetVM() {
|
||||
return compilerTargetVM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Options#getCompilerSourceVM
|
||||
*/
|
||||
public String getCompilerSourceVM() {
|
||||
return compilerSourceVM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Java compiler class to use.
|
||||
*/
|
||||
public String getCompilerClassName() {
|
||||
return compilerClassName;
|
||||
}
|
||||
|
||||
public boolean getErrorOnUseBeanInvalidClassAttribute() {
|
||||
return errorOnUseBeanInvalidClassAttribute;
|
||||
}
|
||||
|
||||
public void setErrorOnUseBeanInvalidClassAttribute(boolean b) {
|
||||
errorOnUseBeanInvalidClassAttribute = b;
|
||||
}
|
||||
|
||||
public TldLocationsCache getTldLocationsCache() {
|
||||
return tldLocationsCache;
|
||||
}
|
||||
|
||||
public void setTldLocationsCache( TldLocationsCache tldC ) {
|
||||
tldLocationsCache = tldC;
|
||||
}
|
||||
|
||||
public String getJavaEncoding() {
|
||||
return javaEncoding;
|
||||
}
|
||||
|
||||
public boolean getFork() {
|
||||
return fork;
|
||||
}
|
||||
|
||||
public JspConfig getJspConfig() {
|
||||
return jspConfig;
|
||||
}
|
||||
|
||||
public TagPluginManager getTagPluginManager() {
|
||||
return tagPluginManager;
|
||||
}
|
||||
|
||||
public boolean isCaching() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map getCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Should we include a source fragment in exception messages, which could be displayed
|
||||
* to the developer ?
|
||||
*/
|
||||
public boolean getDisplaySourceFragment() {
|
||||
return displaySourceFragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an EmbeddedServletOptions object using data available from
|
||||
* ServletConfig and ServletContext.
|
||||
*
|
||||
* @param config servlet config
|
||||
* @param context servlet context
|
||||
*/
|
||||
public EmbeddedServletOptions(ServletConfig config,
|
||||
ServletContext context) {
|
||||
|
||||
// JVM version numbers
|
||||
try {
|
||||
if (Float.parseFloat(System.getProperty("java.specification.version")) > 1.4) {
|
||||
compilerSourceVM = compilerTargetVM = "1.5";
|
||||
} else {
|
||||
compilerSourceVM = compilerTargetVM = "1.4";
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
Enumeration enumeration=config.getInitParameterNames();
|
||||
while( enumeration.hasMoreElements() ) {
|
||||
String k=(String)enumeration.nextElement();
|
||||
String v=config.getInitParameter( k );
|
||||
setProperty( k, v);
|
||||
}
|
||||
|
||||
// quick hack
|
||||
String validating=config.getInitParameter( "validating");
|
||||
if( "false".equals( validating )) ParserUtils.validating=false;
|
||||
|
||||
String keepgen = config.getInitParameter("keepgenerated");
|
||||
if (keepgen != null) {
|
||||
if (keepgen.equalsIgnoreCase("true")) {
|
||||
this.keepGenerated = true;
|
||||
} else if (keepgen.equalsIgnoreCase("false")) {
|
||||
this.keepGenerated = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.keepgen"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String trimsp = config.getInitParameter("trimSpaces");
|
||||
if (trimsp != null) {
|
||||
if (trimsp.equalsIgnoreCase("true")) {
|
||||
trimSpaces = true;
|
||||
} else if (trimsp.equalsIgnoreCase("false")) {
|
||||
trimSpaces = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.trimspaces"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.isPoolingEnabled = true;
|
||||
String poolingEnabledParam
|
||||
= config.getInitParameter("enablePooling");
|
||||
if (poolingEnabledParam != null
|
||||
&& !poolingEnabledParam.equalsIgnoreCase("true")) {
|
||||
if (poolingEnabledParam.equalsIgnoreCase("false")) {
|
||||
this.isPoolingEnabled = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.enablePooling"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String mapFile = config.getInitParameter("mappedfile");
|
||||
if (mapFile != null) {
|
||||
if (mapFile.equalsIgnoreCase("true")) {
|
||||
this.mappedFile = true;
|
||||
} else if (mapFile.equalsIgnoreCase("false")) {
|
||||
this.mappedFile = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.mappedFile"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String debugInfo = config.getInitParameter("classdebuginfo");
|
||||
if (debugInfo != null) {
|
||||
if (debugInfo.equalsIgnoreCase("true")) {
|
||||
this.classDebugInfo = true;
|
||||
} else if (debugInfo.equalsIgnoreCase("false")) {
|
||||
this.classDebugInfo = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.classDebugInfo"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String checkInterval = config.getInitParameter("checkInterval");
|
||||
if (checkInterval != null) {
|
||||
try {
|
||||
this.checkInterval = Integer.parseInt(checkInterval);
|
||||
} catch(NumberFormatException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.checkInterval"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String modificationTestInterval = config.getInitParameter("modificationTestInterval");
|
||||
if (modificationTestInterval != null) {
|
||||
try {
|
||||
this.modificationTestInterval = Integer.parseInt(modificationTestInterval);
|
||||
} catch(NumberFormatException ex) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.modificationTestInterval"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String development = config.getInitParameter("development");
|
||||
if (development != null) {
|
||||
if (development.equalsIgnoreCase("true")) {
|
||||
this.development = true;
|
||||
} else if (development.equalsIgnoreCase("false")) {
|
||||
this.development = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.development"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String suppressSmap = config.getInitParameter("suppressSmap");
|
||||
if (suppressSmap != null) {
|
||||
if (suppressSmap.equalsIgnoreCase("true")) {
|
||||
isSmapSuppressed = true;
|
||||
} else if (suppressSmap.equalsIgnoreCase("false")) {
|
||||
isSmapSuppressed = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.suppressSmap"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String dumpSmap = config.getInitParameter("dumpSmap");
|
||||
if (dumpSmap != null) {
|
||||
if (dumpSmap.equalsIgnoreCase("true")) {
|
||||
isSmapDumped = true;
|
||||
} else if (dumpSmap.equalsIgnoreCase("false")) {
|
||||
isSmapDumped = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.dumpSmap"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String genCharArray = config.getInitParameter("genStrAsCharArray");
|
||||
if (genCharArray != null) {
|
||||
if (genCharArray.equalsIgnoreCase("true")) {
|
||||
genStringAsCharArray = true;
|
||||
} else if (genCharArray.equalsIgnoreCase("false")) {
|
||||
genStringAsCharArray = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.genchararray"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String errBeanClass =
|
||||
config.getInitParameter("errorOnUseBeanInvalidClassAttribute");
|
||||
if (errBeanClass != null) {
|
||||
if (errBeanClass.equalsIgnoreCase("true")) {
|
||||
errorOnUseBeanInvalidClassAttribute = true;
|
||||
} else if (errBeanClass.equalsIgnoreCase("false")) {
|
||||
errorOnUseBeanInvalidClassAttribute = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.errBean"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String ieClassId = config.getInitParameter("ieClassId");
|
||||
if (ieClassId != null)
|
||||
this.ieClassId = ieClassId;
|
||||
|
||||
String classpath = config.getInitParameter("classpath");
|
||||
if (classpath != null)
|
||||
this.classpath = classpath;
|
||||
|
||||
/*
|
||||
* scratchdir
|
||||
*/
|
||||
String dir = config.getInitParameter("scratchdir");
|
||||
if (dir != null) {
|
||||
scratchDir = new File(dir);
|
||||
} else {
|
||||
// First try the Servlet 2.2 jakarta.servlet.context.tempdir property
|
||||
scratchDir = (File) context.getAttribute(Constants.TMP_DIR);
|
||||
if (scratchDir == null) {
|
||||
// Not running in a Servlet 2.2 container.
|
||||
// Try to get the JDK 1.2 java.io.tmpdir property
|
||||
dir = System.getProperty("java.io.tmpdir");
|
||||
if (dir != null)
|
||||
scratchDir = new File(dir);
|
||||
}
|
||||
}
|
||||
if (this.scratchDir == null) {
|
||||
log.fatal(Localizer.getMessage("jsp.error.no.scratch.dir"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(scratchDir.exists() && scratchDir.canRead() &&
|
||||
scratchDir.canWrite() && scratchDir.isDirectory()))
|
||||
log.fatal(Localizer.getMessage("jsp.error.bad.scratch.dir",
|
||||
scratchDir.getAbsolutePath()));
|
||||
|
||||
this.compiler = config.getInitParameter("compiler");
|
||||
|
||||
String compilerTargetVM = config.getInitParameter("compilerTargetVM");
|
||||
if(compilerTargetVM != null) {
|
||||
this.compilerTargetVM = compilerTargetVM;
|
||||
}
|
||||
|
||||
String compilerSourceVM = config.getInitParameter("compilerSourceVM");
|
||||
if(compilerSourceVM != null) {
|
||||
this.compilerSourceVM = compilerSourceVM;
|
||||
}
|
||||
|
||||
String javaEncoding = config.getInitParameter("javaEncoding");
|
||||
if (javaEncoding != null) {
|
||||
this.javaEncoding = javaEncoding;
|
||||
}
|
||||
|
||||
String compilerClassName = config.getInitParameter("compilerClassName");
|
||||
if (compilerClassName != null) {
|
||||
this.compilerClassName = compilerClassName;
|
||||
}
|
||||
|
||||
String fork = config.getInitParameter("fork");
|
||||
if (fork != null) {
|
||||
if (fork.equalsIgnoreCase("true")) {
|
||||
this.fork = true;
|
||||
} else if (fork.equalsIgnoreCase("false")) {
|
||||
this.fork = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.fork"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String xpoweredBy = config.getInitParameter("xpoweredBy");
|
||||
if (xpoweredBy != null) {
|
||||
if (xpoweredBy.equalsIgnoreCase("true")) {
|
||||
this.xpoweredBy = true;
|
||||
} else if (xpoweredBy.equalsIgnoreCase("false")) {
|
||||
this.xpoweredBy = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.xpoweredBy"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String displaySourceFragment = config.getInitParameter("displaySourceFragment");
|
||||
if (displaySourceFragment != null) {
|
||||
if (displaySourceFragment.equalsIgnoreCase("true")) {
|
||||
this.displaySourceFragment = true;
|
||||
} else if (displaySourceFragment.equalsIgnoreCase("false")) {
|
||||
this.displaySourceFragment = false;
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage("jsp.warning.displaySourceFragment"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the global Tag Libraries location cache for this
|
||||
// web-application.
|
||||
tldLocationsCache = new TldLocationsCache(context);
|
||||
|
||||
// Setup the jsp config info for this web app.
|
||||
jspConfig = new JspConfig(context);
|
||||
|
||||
// Create a Tag plugin instance
|
||||
tagPluginManager = new TagPluginManager(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +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.struts2.jasper;
|
||||
|
||||
/**
|
||||
* Base class for all exceptions generated by the JSP engine. Makes it
|
||||
* convenient to catch just this at the top-level.
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
*/
|
||||
public class JasperException extends jakarta.servlet.ServletException {
|
||||
|
||||
public JasperException(String reason) {
|
||||
super(reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JasperException with the embedded exception and the reason for
|
||||
* throwing a JasperException
|
||||
*
|
||||
* @param reason the reason
|
||||
* @param exception the exception
|
||||
*/
|
||||
public JasperException (String reason, Throwable exception) {
|
||||
super(reason, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JasperException with the embedded exception
|
||||
*
|
||||
* @param exception the exception
|
||||
*/
|
||||
public JasperException (Throwable exception) {
|
||||
super(exception);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
-732
@@ -1,732 +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.struts2.jasper;
|
||||
|
||||
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.jasper.compiler.Compiler;
|
||||
import org.apache.struts2.jasper.compiler.JspRuntimeContext;
|
||||
import org.apache.struts2.jasper.compiler.JspUtil;
|
||||
import org.apache.struts2.jasper.compiler.Localizer;
|
||||
import org.apache.struts2.jasper.compiler.ServletWriter;
|
||||
import org.apache.struts2.jasper.servlet.JasperLoader;
|
||||
import org.apache.struts2.jasper.servlet.JspServletWrapper;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.jsp.tagext.TagInfo;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A place holder for various things that are used through out the JSP
|
||||
* engine. This is a per-request/per-context data structure. Some of
|
||||
* the instance variables are set at different points.
|
||||
*
|
||||
* Most of the path-related stuff is here - mangling names, versions, dirs,
|
||||
* loading resources and dealing with uris.
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
* @author Harish Prabandham
|
||||
* @author Pierre Delisle
|
||||
* @author Costin Manolache
|
||||
* @author Kin-man Chung
|
||||
*/
|
||||
public class JspCompilationContext {
|
||||
|
||||
protected org.apache.juli.logging.Log log =
|
||||
org.apache.juli.logging.LogFactory.getLog(JspCompilationContext.class);
|
||||
|
||||
protected Map<String, URL> tagFileJarUrls;
|
||||
protected boolean isPackagedTagFile;
|
||||
|
||||
protected String className;
|
||||
protected String jspUri;
|
||||
protected boolean isErrPage;
|
||||
protected String basePackageName;
|
||||
protected String derivedPackageName;
|
||||
protected String servletJavaFileName;
|
||||
protected String javaPath;
|
||||
protected String classFileName;
|
||||
protected String contentType;
|
||||
protected ServletWriter writer;
|
||||
protected Options options;
|
||||
protected JspServletWrapper jsw;
|
||||
protected Compiler jspCompiler;
|
||||
protected String classPath;
|
||||
|
||||
protected String baseURI;
|
||||
protected String outputDir;
|
||||
protected ServletContext context;
|
||||
protected ClassLoader loader;
|
||||
|
||||
protected JspRuntimeContext rctxt;
|
||||
|
||||
protected int removed = 0;
|
||||
|
||||
protected URLClassLoader jspLoader;
|
||||
protected URL baseUrl;
|
||||
protected Class servletClass;
|
||||
|
||||
protected boolean isTagFile;
|
||||
protected boolean protoTypeMode;
|
||||
protected TagInfo tagInfo;
|
||||
protected URL tagFileJarUrl;
|
||||
private ClassLoaderInterface classLoaderInterface;
|
||||
private String sourceCode;
|
||||
|
||||
// jspURI _must_ be relative to the context
|
||||
public JspCompilationContext(String jspUri,
|
||||
boolean isErrPage,
|
||||
Options options,
|
||||
ServletContext context,
|
||||
JspServletWrapper jsw,
|
||||
JspRuntimeContext rctxt,
|
||||
ClassLoaderInterface classLoaderInterface) {
|
||||
|
||||
this.jspUri = canonicalURI(jspUri);
|
||||
this.isErrPage = isErrPage;
|
||||
this.options = options;
|
||||
this.jsw = jsw;
|
||||
this.context = context;
|
||||
|
||||
this.baseURI = jspUri.substring(0, jspUri.lastIndexOf('/') + 1);
|
||||
// hack fix for resolveRelativeURI
|
||||
if (baseURI == null) {
|
||||
baseURI = "/";
|
||||
} else if (baseURI.charAt(0) != '/') {
|
||||
// strip the basde slash since it will be combined with the
|
||||
// uriBase to generate a file
|
||||
baseURI = "/" + baseURI;
|
||||
}
|
||||
if (baseURI.charAt(baseURI.length() - 1) != '/') {
|
||||
baseURI += '/';
|
||||
}
|
||||
|
||||
this.rctxt = rctxt;
|
||||
this.tagFileJarUrls = new HashMap<>();
|
||||
this.basePackageName = Constants.JSP_PACKAGE_NAME;
|
||||
this.classLoaderInterface = classLoaderInterface;
|
||||
}
|
||||
|
||||
public JspCompilationContext(String tagfile,
|
||||
TagInfo tagInfo,
|
||||
Options options,
|
||||
ServletContext context,
|
||||
JspServletWrapper jsw,
|
||||
JspRuntimeContext rctxt,
|
||||
URL tagFileJarUrl) {
|
||||
this(tagfile, false, options, context, jsw, rctxt, null);
|
||||
this.isTagFile = true;
|
||||
this.tagInfo = tagInfo;
|
||||
this.tagFileJarUrl = tagFileJarUrl;
|
||||
if (tagFileJarUrl != null) {
|
||||
isPackagedTagFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== Methods to override ==================== */
|
||||
|
||||
/** ---------- Class path and loader ---------- */
|
||||
|
||||
/**
|
||||
* @return The classpath that is passed off to the Java compiler.
|
||||
*/
|
||||
public String getClassPath() {
|
||||
if( classPath != null )
|
||||
return classPath;
|
||||
return rctxt.getClassPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param classPath The classpath that is passed off to the Java compiler.
|
||||
*/
|
||||
public void setClassPath(String classPath) {
|
||||
this.classPath = classPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return What class loader to use for loading classes while compiling
|
||||
* this JSP?
|
||||
*/
|
||||
public ClassLoader getClassLoader() {
|
||||
if( loader != null )
|
||||
return loader;
|
||||
return rctxt.getParentClassLoader();
|
||||
}
|
||||
|
||||
public void setClassLoader(ClassLoader loader) {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public ClassLoader getJspLoader() {
|
||||
if( jspLoader == null ) {
|
||||
jspLoader = new JasperLoader
|
||||
(new URL[] {baseUrl},
|
||||
getClassLoader(),
|
||||
rctxt.getPermissionCollection(),
|
||||
rctxt.getCodeSource());
|
||||
}
|
||||
return jspLoader;
|
||||
}
|
||||
|
||||
/** ---------- Input/Output ---------- */
|
||||
|
||||
/**
|
||||
* @return The output directory to generate code into. The output directory
|
||||
* is make up of the scratch directory, which is provide in Options,
|
||||
* plus the directory derived from the package name.
|
||||
*/
|
||||
public String getOutputDir() {
|
||||
if (outputDir == null) {
|
||||
createOutputDir();
|
||||
}
|
||||
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Create a "Compiler" object based on some init param data. This
|
||||
* is not done yet. Right now we're just hardcoding the actual
|
||||
* compilers that are created.
|
||||
*
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public Compiler createCompiler() throws JasperException {
|
||||
jspCompiler = new CustomCompiler();
|
||||
jspCompiler.init(this, jsw);
|
||||
return jspCompiler;
|
||||
}
|
||||
|
||||
protected Compiler createCompiler(String className) {
|
||||
Compiler compiler = null;
|
||||
try {
|
||||
compiler = (Compiler) Class.forName(className).newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
log.warn(Localizer.getMessage("jsp.error.compiler"), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
log.warn(Localizer.getMessage("jsp.error.compiler"), e);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.error.compiler"), e);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(Localizer.getMessage("jsp.error.compiler"), e);
|
||||
}
|
||||
}
|
||||
return compiler;
|
||||
}
|
||||
|
||||
public Compiler getCompiler() {
|
||||
return jspCompiler;
|
||||
}
|
||||
|
||||
/** ---------- Access resources in the webapp ---------- */
|
||||
|
||||
/**
|
||||
* Get the full value of a URI relative to this compilations context
|
||||
* uses current file as the base.
|
||||
*
|
||||
* @param uri the URL
|
||||
* @return full URL
|
||||
*/
|
||||
public String resolveRelativeUri(String uri) {
|
||||
// sometimes we get uri's massaged from File(String), so check for
|
||||
// a root directory deperator char
|
||||
if (uri.startsWith("/") || uri.startsWith(File.separator)) {
|
||||
return uri;
|
||||
} else {
|
||||
return baseURI + uri;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a resource as a stream, relative to the meanings of this
|
||||
* context's implementation.
|
||||
*
|
||||
* @param res resource
|
||||
* @return a null if the resource cannot be found or represented
|
||||
* as an InputStream.
|
||||
*/
|
||||
public java.io.InputStream getResourceAsStream(String res) {
|
||||
try {
|
||||
return classLoaderInterface.getResourceAsStream(canonicalURI(StringUtils.removeStart(res, "/")));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public URL getResource(String res) throws MalformedURLException {
|
||||
return classLoaderInterface.getResource(canonicalURI(StringUtils.removeStart(res, "/")));
|
||||
}
|
||||
|
||||
|
||||
public Set getResourcePaths(String path) {
|
||||
return context.getResourcePaths(canonicalURI(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path the path
|
||||
*
|
||||
* @return the actual path of a URI relative to the context of
|
||||
* the compilation.
|
||||
*/
|
||||
public String getRealPath(String path) {
|
||||
if (context != null) {
|
||||
return context.getRealPath(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tag-file-name-to-JAR-file map of this compilation unit,
|
||||
* which maps tag file names to the JAR files in which the tag files are
|
||||
* packaged.
|
||||
*
|
||||
* @param tagFile The map is populated when parsing the tag-file elements of the TLDs
|
||||
* of any imported taglibs.
|
||||
*/
|
||||
public URL getTagFileJarUrl(String tagFile) {
|
||||
return this.tagFileJarUrls.get(tagFile);
|
||||
}
|
||||
|
||||
public void setTagFileJarUrl(String tagFile, URL tagFileURL) {
|
||||
this.tagFileJarUrls.put(tagFile, tagFileURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the JAR file in which the tag file for which this
|
||||
* JspCompilationContext was created is packaged, or null if this
|
||||
* JspCompilationContext does not correspond to a tag file, or if the
|
||||
* corresponding tag file is not packaged in a JAR.
|
||||
*/
|
||||
public URL getTagFileJarUrl() {
|
||||
return this.tagFileJarUrl;
|
||||
}
|
||||
|
||||
/* ==================== Common implementation ==================== */
|
||||
|
||||
/**
|
||||
* @return Just the class name (does not include package name) of the
|
||||
* generated class.
|
||||
*/
|
||||
public String getServletClassName() {
|
||||
|
||||
if (className != null) {
|
||||
return className;
|
||||
}
|
||||
|
||||
if (isTagFile) {
|
||||
className = tagInfo.getTagClassName();
|
||||
int lastIndex = className.lastIndexOf('.');
|
||||
if (lastIndex != -1) {
|
||||
className = className.substring(lastIndex + 1);
|
||||
}
|
||||
} else {
|
||||
int iSep = jspUri.lastIndexOf('/') + 1;
|
||||
className = JspUtil.makeJavaIdentifier(jspUri.substring(iSep));
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setServletClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Path of the JSP URI. Note that this is not a file name. This is
|
||||
* the context rooted URI of the JSP file.
|
||||
*/
|
||||
public String getJspFile() {
|
||||
return jspUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Are we processing something that has been declared as an
|
||||
* errorpage?
|
||||
*/
|
||||
public boolean isErrorPage() {
|
||||
return isErrPage;
|
||||
}
|
||||
|
||||
public void setErrorPage(boolean isErrPage) {
|
||||
this.isErrPage = isErrPage;
|
||||
}
|
||||
|
||||
public boolean isTagFile() {
|
||||
return isTagFile;
|
||||
}
|
||||
|
||||
public TagInfo getTagInfo() {
|
||||
return tagInfo;
|
||||
}
|
||||
|
||||
public void setTagInfo(TagInfo tagi) {
|
||||
tagInfo = tagi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if we are compiling a tag file in prototype mode.
|
||||
* ie we only generate codes with class for the tag handler with empty
|
||||
* method bodies.
|
||||
*/
|
||||
public boolean isPrototypeMode() {
|
||||
return protoTypeMode;
|
||||
}
|
||||
|
||||
public void setPrototypeMode(boolean pm) {
|
||||
protoTypeMode = pm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Package name for the generated class is make up of the base package
|
||||
* name, which is user settable, and the derived package name. The
|
||||
* derived package name directly mirrors the file heirachy of the JSP page.
|
||||
*/
|
||||
public String getServletPackageName() {
|
||||
if (isTagFile()) {
|
||||
String className = tagInfo.getTagClassName();
|
||||
int lastIndex = className.lastIndexOf('.');
|
||||
String pkgName = "";
|
||||
if (lastIndex != -1) {
|
||||
pkgName = className.substring(0, lastIndex);
|
||||
}
|
||||
return pkgName;
|
||||
} else {
|
||||
String dPackageName = getDerivedPackageName();
|
||||
if (dPackageName.length() == 0) {
|
||||
return basePackageName;
|
||||
}
|
||||
return basePackageName + '.' + getDerivedPackageName();
|
||||
}
|
||||
}
|
||||
|
||||
protected String getDerivedPackageName() {
|
||||
if (derivedPackageName == null) {
|
||||
int iSep = jspUri.lastIndexOf('/');
|
||||
derivedPackageName = (iSep > 0) ?
|
||||
JspUtil.makeJavaPackage(jspUri.substring(1,iSep)) : "";
|
||||
}
|
||||
return derivedPackageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param servletPackageName The package name into which the servlet class is generated.
|
||||
*/
|
||||
public void setServletPackageName(String servletPackageName) {
|
||||
this.basePackageName = servletPackageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Full path name of the Java file into which the servlet is being
|
||||
* generated.
|
||||
*/
|
||||
public String getServletJavaFileName() {
|
||||
if (servletJavaFileName == null) {
|
||||
servletJavaFileName = getOutputDir() + getServletClassName() + ".java";
|
||||
}
|
||||
return servletJavaFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Get hold of the Options object for this context.
|
||||
*/
|
||||
public Options getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public ServletContext getServletContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public JspRuntimeContext getRuntimeContext() {
|
||||
return rctxt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Path of the Java file relative to the work directory.
|
||||
*/
|
||||
public String getJavaPath() {
|
||||
|
||||
if (javaPath != null) {
|
||||
return javaPath;
|
||||
}
|
||||
|
||||
if (isTagFile()) {
|
||||
String tagName = tagInfo.getTagClassName();
|
||||
javaPath = tagName.replace('.', '/') + ".java";
|
||||
} else {
|
||||
javaPath = getServletPackageName().replace('.', '/') + '/' +
|
||||
getServletClassName() + ".java";
|
||||
}
|
||||
return javaPath;
|
||||
}
|
||||
|
||||
public String getClassFileName() {
|
||||
if (classFileName == null) {
|
||||
classFileName = getOutputDir() + getServletClassName() + ".class";
|
||||
}
|
||||
return classFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Get the content type of this JSP.
|
||||
*
|
||||
* Content type includes content type and encoding.
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Where is the servlet being generated?
|
||||
*/
|
||||
public ServletWriter getWriter() {
|
||||
return writer;
|
||||
}
|
||||
|
||||
public void setWriter(ServletWriter writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'location' of the TLD associated with the given taglib 'uri'.
|
||||
*
|
||||
* @param uri the URL
|
||||
*
|
||||
* @return An array of two Strings: The first element denotes the real
|
||||
* path to the TLD. If the path to the TLD points to a jar file, then the
|
||||
* second element denotes the name of the TLD entry in the jar file.
|
||||
* Returns null if the given uri is not associated with any tag library
|
||||
* 'exposed' in the web application.
|
||||
*
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public String[] getTldLocation(String uri) throws JasperException {
|
||||
String[] location =
|
||||
getOptions().getTldLocationsCache().getLocation(uri);
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Are we keeping generated code around?
|
||||
*/
|
||||
public boolean keepGenerated() {
|
||||
return getOptions().getKeepGenerated();
|
||||
}
|
||||
|
||||
// ==================== Removal ====================
|
||||
|
||||
public void incrementRemoved() {
|
||||
if (removed == 0 && rctxt != null) {
|
||||
rctxt.removeWrapper(jspUri);
|
||||
}
|
||||
removed++;
|
||||
}
|
||||
|
||||
public boolean isRemoved() {
|
||||
if (removed > 1 ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ==================== Compile and reload ====================
|
||||
|
||||
public void compile() throws JasperException, FileNotFoundException {
|
||||
createCompiler();
|
||||
if (jspCompiler.isOutDated()) {
|
||||
try {
|
||||
jspCompiler.removeGeneratedFiles();
|
||||
jspLoader = null;
|
||||
jspCompiler.compile();
|
||||
jsw.setReload(true);
|
||||
jsw.setCompilationException(null);
|
||||
} catch (JasperException ex) {
|
||||
// Cache compilation exception
|
||||
jsw.setCompilationException(ex);
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
JasperException je = new JasperException(
|
||||
Localizer.getMessage("jsp.error.unable.compile"),
|
||||
ex);
|
||||
// Cache compilation exception
|
||||
jsw.setCompilationException(je);
|
||||
throw je;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Manipulating the class ====================
|
||||
|
||||
public Class load()
|
||||
throws JasperException, FileNotFoundException
|
||||
{
|
||||
try {
|
||||
getJspLoader();
|
||||
|
||||
String name;
|
||||
if (isTagFile()) {
|
||||
name = tagInfo.getTagClassName();
|
||||
} else {
|
||||
name = getServletPackageName() + "." + getServletClassName();
|
||||
}
|
||||
servletClass = jspLoader.loadClass(name);
|
||||
} catch (ClassNotFoundException cex) {
|
||||
throw new JasperException(Localizer.getMessage("jsp.error.unable.load"),
|
||||
cex);
|
||||
} catch (Exception ex) {
|
||||
throw new JasperException(Localizer.getMessage("jsp.error.unable.compile"),
|
||||
ex);
|
||||
}
|
||||
removed = 0;
|
||||
return servletClass;
|
||||
}
|
||||
|
||||
// ==================== protected methods ====================
|
||||
|
||||
static Object outputDirLock = new Object();
|
||||
|
||||
public void checkOutputDir() {
|
||||
if (outputDir != null) {
|
||||
if (!(new File(outputDir)).exists()) {
|
||||
makeOutputDir();
|
||||
}
|
||||
} else {
|
||||
createOutputDir();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean makeOutputDir() {
|
||||
synchronized(outputDirLock) {
|
||||
File outDirFile = new File(outputDir);
|
||||
return (outDirFile.exists() || outDirFile.mkdirs());
|
||||
}
|
||||
}
|
||||
|
||||
protected void createOutputDir() {
|
||||
String path = null;
|
||||
if (isTagFile()) {
|
||||
String tagName = tagInfo.getTagClassName();
|
||||
path = tagName.replace('.', File.separatorChar);
|
||||
path = path.substring(0, path.lastIndexOf(File.separatorChar));
|
||||
} else {
|
||||
path = getServletPackageName().replace('.',File.separatorChar);
|
||||
}
|
||||
|
||||
// Append servlet or tag handler path to scratch dir
|
||||
try {
|
||||
File base = options.getScratchDir();
|
||||
baseUrl = base.toURI().toURL();
|
||||
outputDir = base.getAbsolutePath() + File.separator + path +
|
||||
File.separator;
|
||||
if (!makeOutputDir()) {
|
||||
throw new IllegalStateException(Localizer.getMessage("jsp.error.outputfolder"));
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalStateException(Localizer.getMessage("jsp.error.outputfolder"), e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static final boolean isPathSeparator(char c) {
|
||||
return (c == '/' || c == '\\');
|
||||
}
|
||||
|
||||
protected static final String canonicalURI(String s) {
|
||||
if (s == null) return null;
|
||||
StringBuffer result = new StringBuffer();
|
||||
final int len = s.length();
|
||||
int pos = 0;
|
||||
while (pos < len) {
|
||||
char c = s.charAt(pos);
|
||||
if ( isPathSeparator(c) ) {
|
||||
/*
|
||||
* multiple path separators.
|
||||
* 'foo///bar' -> 'foo/bar'
|
||||
*/
|
||||
while (pos+1 < len && isPathSeparator(s.charAt(pos+1))) {
|
||||
++pos;
|
||||
}
|
||||
|
||||
if (pos+1 < len && s.charAt(pos+1) == '.') {
|
||||
/*
|
||||
* a single dot at the end of the path - we are done.
|
||||
*/
|
||||
if (pos+2 >= len) break;
|
||||
|
||||
switch (s.charAt(pos+2)) {
|
||||
/*
|
||||
* self directory in path
|
||||
* foo/./bar -> foo/bar
|
||||
*/
|
||||
case '/':
|
||||
case '\\':
|
||||
pos += 2;
|
||||
continue;
|
||||
|
||||
/*
|
||||
* two dots in a path: go back one hierarchy.
|
||||
* foo/bar/../baz -> foo/baz
|
||||
*/
|
||||
case '.':
|
||||
// only if we have exactly _two_ dots.
|
||||
if (pos+3 < len && isPathSeparator(s.charAt(pos+3))) {
|
||||
pos += 3;
|
||||
int separatorPos = result.length()-1;
|
||||
while (separatorPos >= 0 &&
|
||||
! isPathSeparator(result
|
||||
.charAt(separatorPos))) {
|
||||
--separatorPos;
|
||||
}
|
||||
if (separatorPos >= 0)
|
||||
result.setLength(separatorPos);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.append(c);
|
||||
++pos;
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public String getSourceCode() {
|
||||
return sourceCode;
|
||||
}
|
||||
|
||||
public void setSourceCode(String sourceCode) {
|
||||
this.sourceCode = sourceCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,196 +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.struts2.jasper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.struts2.jasper.compiler.JspConfig;
|
||||
import org.apache.struts2.jasper.compiler.TagPluginManager;
|
||||
import org.apache.struts2.jasper.compiler.TldLocationsCache;
|
||||
|
||||
/**
|
||||
* A class to hold all init parameters specific to the JSP engine.
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
* @author Hans Bergsten
|
||||
* @author Pierre Delisle
|
||||
*/
|
||||
public interface Options {
|
||||
|
||||
/**
|
||||
* @return true if Jasper issues a compilation error instead of a runtime
|
||||
* Instantiation error if the class attribute specified in useBean action
|
||||
* is invalid.
|
||||
*/
|
||||
public boolean getErrorOnUseBeanInvalidClassAttribute();
|
||||
|
||||
/**
|
||||
* @return Are we keeping generated code around?
|
||||
*/
|
||||
public boolean getKeepGenerated();
|
||||
|
||||
/**
|
||||
* @return true if tag handler pooling is enabled, false otherwise.
|
||||
*/
|
||||
public boolean isPoolingEnabled();
|
||||
|
||||
/**
|
||||
* @return Are we supporting HTML mapped servlets?
|
||||
*/
|
||||
public boolean getMappedFile();
|
||||
|
||||
/**
|
||||
* @return Should we include debug information in compiled class?
|
||||
*/
|
||||
public boolean getClassDebugInfo();
|
||||
|
||||
/**
|
||||
* @return Background compile thread check interval in seconds
|
||||
*/
|
||||
public int getCheckInterval();
|
||||
|
||||
/**
|
||||
* @return Is Jasper being used in development mode?
|
||||
*/
|
||||
public boolean getDevelopment();
|
||||
|
||||
/**
|
||||
* @return Should we include a source fragment in exception messages, which could be displayed
|
||||
* to the developer ?
|
||||
*/
|
||||
public boolean getDisplaySourceFragment();
|
||||
|
||||
/**
|
||||
* @return Is the generation of SMAP info for JSR45 debugging suppressed?
|
||||
*/
|
||||
public boolean isSmapSuppressed();
|
||||
|
||||
/**
|
||||
* @return Indicates whether SMAP info for JSR45 debugging should be dumped to a
|
||||
* file.
|
||||
* Ignored is suppressSmap() is true
|
||||
*/
|
||||
public boolean isSmapDumped();
|
||||
|
||||
/**
|
||||
* @return Should white spaces between directives or actions be trimmed?
|
||||
*/
|
||||
public boolean getTrimSpaces();
|
||||
|
||||
/**
|
||||
* @return Class ID for use in the plugin tag when the browser is IE.
|
||||
*/
|
||||
public String getIeClassId();
|
||||
|
||||
/**
|
||||
* @return What is my scratch dir?
|
||||
*/
|
||||
public File getScratchDir();
|
||||
|
||||
/**
|
||||
* @return What classpath should I use while compiling the servlets
|
||||
* generated from JSP files?
|
||||
*/
|
||||
public String getClassPath();
|
||||
|
||||
/**
|
||||
* @return Compiler to use.
|
||||
*/
|
||||
public String getCompiler();
|
||||
|
||||
/**
|
||||
* @return The compiler target VM, e.g. 1.1, 1.2, 1.3, 1.4, or 1.5.
|
||||
*/
|
||||
public String getCompilerTargetVM();
|
||||
|
||||
/**
|
||||
* @return Compiler source VM, e.g. 1.3, 1.4, or 1.5.
|
||||
*/
|
||||
public String getCompilerSourceVM();
|
||||
|
||||
/**
|
||||
* @return Java compiler class to use.
|
||||
*/
|
||||
public String getCompilerClassName();
|
||||
|
||||
/**
|
||||
* The cache for the location of the TLD's
|
||||
* for the various tag libraries 'exposed'
|
||||
* by the web application.
|
||||
* A tag library is 'exposed' either explicitely in
|
||||
* web.xml or implicitely via the uri tag in the TLD
|
||||
* of a taglib deployed in a jar file (WEB-INF/lib).
|
||||
*
|
||||
* @return the instance of the TldLocationsCache
|
||||
* for the web-application.
|
||||
*/
|
||||
public TldLocationsCache getTldLocationsCache();
|
||||
|
||||
/**
|
||||
* @return Java platform encoding to generate the JSP
|
||||
* page servlet.
|
||||
*/
|
||||
public String getJavaEncoding();
|
||||
|
||||
/**
|
||||
* @return boolean flag to tell Ant whether to fork JSP page compilations.
|
||||
*/
|
||||
public boolean getFork();
|
||||
|
||||
/**
|
||||
* @return Obtain JSP configuration information specified in web.xml.
|
||||
*/
|
||||
public JspConfig getJspConfig();
|
||||
|
||||
/**
|
||||
* @return Is generation of X-Powered-By response header enabled/disabled?
|
||||
*/
|
||||
public boolean isXpoweredBy();
|
||||
|
||||
/**
|
||||
* @return Obtain a Tag Plugin Manager
|
||||
*/
|
||||
public TagPluginManager getTagPluginManager();
|
||||
|
||||
/**
|
||||
* @return Are Text strings to be generated as char arrays?
|
||||
*/
|
||||
public boolean genStringAsCharArray();
|
||||
|
||||
/**
|
||||
* @return Modification test interval.
|
||||
*/
|
||||
public int getModificationTestInterval();
|
||||
|
||||
/**
|
||||
* @return Is caching enabled (used for precompilation).
|
||||
*/
|
||||
public boolean isCaching();
|
||||
|
||||
/**
|
||||
* The web-application wide cache for the returned TreeNode
|
||||
* by parseXMLDocument in TagLibraryInfoImpl.parseTLD,
|
||||
* if isCaching returns true.
|
||||
*
|
||||
* @return the Map(String uri, TreeNode tld) instance.
|
||||
*/
|
||||
public Map getCache();
|
||||
|
||||
}
|
||||
-79
@@ -1,79 +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.struts2.jasper.compiler;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
|
||||
/**
|
||||
* Repository of {page, request, session, application}-scoped beans
|
||||
*
|
||||
* @author Mandar Raje
|
||||
* @author Remy Maucherat
|
||||
*/
|
||||
public class BeanRepository {
|
||||
|
||||
protected HashMap<String, String> beanTypes;
|
||||
protected ClassLoader loader;
|
||||
protected ErrorDispatcher errDispatcher;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param loader class loader
|
||||
* @param err the error dispatcher
|
||||
*/
|
||||
public BeanRepository(ClassLoader loader, ErrorDispatcher err) {
|
||||
this.loader = loader;
|
||||
this.errDispatcher = err;
|
||||
beanTypes = new HashMap<>();
|
||||
}
|
||||
|
||||
public void addBean(Node.UseBean n, String s, String type, String scope)
|
||||
throws JasperException {
|
||||
|
||||
if (!(scope == null || scope.equals("page") || scope.equals("request")
|
||||
|| scope.equals("session") || scope.equals("application"))) {
|
||||
errDispatcher.jspError(n, "jsp.error.usebean.badScope");
|
||||
}
|
||||
|
||||
beanTypes.put(s, type);
|
||||
}
|
||||
|
||||
public Class getBeanType(String bean)
|
||||
throws JasperException {
|
||||
Class clazz = null;
|
||||
try {
|
||||
clazz = loader.loadClass(beanTypes.get(bean));
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new JasperException (ex);
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public boolean checkVariable(String bean) {
|
||||
return beanTypes.containsKey(bean);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,205 +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.struts2.jasper.compiler;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
|
||||
/**
|
||||
* Collect info about the page and nodes, and make them availabe through
|
||||
* the PageInfo object.
|
||||
*
|
||||
* @author Kin-man Chung
|
||||
* @author Mark Roth
|
||||
*/
|
||||
|
||||
class Collector {
|
||||
|
||||
/**
|
||||
* A visitor for collecting information on the page and the body of
|
||||
* the custom tags.
|
||||
*/
|
||||
static class CollectVisitor extends Node.Visitor {
|
||||
|
||||
private boolean scriptingElementSeen = false;
|
||||
private boolean usebeanSeen = false;
|
||||
private boolean includeActionSeen = false;
|
||||
private boolean paramActionSeen = false;
|
||||
private boolean setPropertySeen = false;
|
||||
private boolean hasScriptingVars = false;
|
||||
|
||||
public void visit(Node.ParamAction n) throws JasperException {
|
||||
if (n.getValue().isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
paramActionSeen = true;
|
||||
}
|
||||
|
||||
public void visit(Node.IncludeAction n) throws JasperException {
|
||||
if (n.getPage().isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
includeActionSeen = true;
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.ForwardAction n) throws JasperException {
|
||||
if (n.getPage().isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.SetProperty n) throws JasperException {
|
||||
if (n.getValue() != null && n.getValue().isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
setPropertySeen = true;
|
||||
}
|
||||
|
||||
public void visit(Node.UseBean n) throws JasperException {
|
||||
if (n.getBeanName() != null && n.getBeanName().isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
usebeanSeen = true;
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.PlugIn n) throws JasperException {
|
||||
if (n.getHeight() != null && n.getHeight().isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
if (n.getWidth() != null && n.getWidth().isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.CustomTag n) throws JasperException {
|
||||
// Check to see what kinds of element we see as child elements
|
||||
checkSeen( n.getChildInfo(), n );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all child nodes for various elements and update the given
|
||||
* ChildInfo object accordingly. Visits body in the process.
|
||||
*/
|
||||
private void checkSeen( Node.ChildInfo ci, Node n )
|
||||
throws JasperException
|
||||
{
|
||||
// save values collected so far
|
||||
boolean scriptingElementSeenSave = scriptingElementSeen;
|
||||
scriptingElementSeen = false;
|
||||
boolean usebeanSeenSave = usebeanSeen;
|
||||
usebeanSeen = false;
|
||||
boolean includeActionSeenSave = includeActionSeen;
|
||||
includeActionSeen = false;
|
||||
boolean paramActionSeenSave = paramActionSeen;
|
||||
paramActionSeen = false;
|
||||
boolean setPropertySeenSave = setPropertySeen;
|
||||
setPropertySeen = false;
|
||||
boolean hasScriptingVarsSave = hasScriptingVars;
|
||||
hasScriptingVars = false;
|
||||
|
||||
// Scan attribute list for expressions
|
||||
if( n instanceof Node.CustomTag ) {
|
||||
Node.CustomTag ct = (Node.CustomTag)n;
|
||||
Node.JspAttribute[] attrs = ct.getJspAttributes();
|
||||
for (int i = 0; attrs != null && i < attrs.length; i++) {
|
||||
if (attrs[i].isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitBody(n);
|
||||
|
||||
if( (n instanceof Node.CustomTag) && !hasScriptingVars) {
|
||||
Node.CustomTag ct = (Node.CustomTag)n;
|
||||
hasScriptingVars = ct.getVariableInfos().length > 0 ||
|
||||
ct.getTagVariableInfos().length > 0;
|
||||
}
|
||||
|
||||
// Record if the tag element and its body contains any scriptlet.
|
||||
ci.setScriptless(! scriptingElementSeen);
|
||||
ci.setHasUseBean(usebeanSeen);
|
||||
ci.setHasIncludeAction(includeActionSeen);
|
||||
ci.setHasParamAction(paramActionSeen);
|
||||
ci.setHasSetProperty(setPropertySeen);
|
||||
ci.setHasScriptingVars(hasScriptingVars);
|
||||
|
||||
// Propagate value of scriptingElementSeen up.
|
||||
scriptingElementSeen = scriptingElementSeen || scriptingElementSeenSave;
|
||||
usebeanSeen = usebeanSeen || usebeanSeenSave;
|
||||
setPropertySeen = setPropertySeen || setPropertySeenSave;
|
||||
includeActionSeen = includeActionSeen || includeActionSeenSave;
|
||||
paramActionSeen = paramActionSeen || paramActionSeenSave;
|
||||
hasScriptingVars = hasScriptingVars || hasScriptingVarsSave;
|
||||
}
|
||||
|
||||
public void visit(Node.JspElement n) throws JasperException {
|
||||
if (n.getNameAttribute().isExpression())
|
||||
scriptingElementSeen = true;
|
||||
|
||||
Node.JspAttribute[] attrs = n.getJspAttributes();
|
||||
for (int i = 0; i < attrs.length; i++) {
|
||||
if (attrs[i].isExpression()) {
|
||||
scriptingElementSeen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.JspBody n) throws JasperException {
|
||||
checkSeen( n.getChildInfo(), n );
|
||||
}
|
||||
|
||||
public void visit(Node.NamedAttribute n) throws JasperException {
|
||||
checkSeen( n.getChildInfo(), n );
|
||||
}
|
||||
|
||||
public void visit(Node.Declaration n) throws JasperException {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
|
||||
public void visit(Node.Expression n) throws JasperException {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
|
||||
public void visit(Node.Scriptlet n) throws JasperException {
|
||||
scriptingElementSeen = true;
|
||||
}
|
||||
|
||||
public void updatePageInfo(PageInfo pageInfo) {
|
||||
pageInfo.setScriptless(! scriptingElementSeen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void collect(Compiler compiler, Node.Nodes page)
|
||||
throws JasperException {
|
||||
|
||||
CollectVisitor collectVisitor = new CollectVisitor();
|
||||
page.visit(collectVisitor);
|
||||
collectVisitor.updatePageInfo(compiler.getPageInfo());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,569 +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.struts2.jasper.compiler;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
import org.apache.struts2.jasper.JspCompilationContext;
|
||||
import org.apache.struts2.jasper.Options;
|
||||
import org.apache.struts2.jasper.servlet.JspServletWrapper;
|
||||
|
||||
/**
|
||||
* Main JSP compiler class. This class uses Ant for compiling.
|
||||
*
|
||||
* @author Anil K. Vijendran
|
||||
* @author Mandar Raje
|
||||
* @author Pierre Delisle
|
||||
* @author Kin-man Chung
|
||||
* @author Remy Maucherat
|
||||
* @author Mark Roth
|
||||
*/
|
||||
public abstract class Compiler {
|
||||
|
||||
protected org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory
|
||||
.getLog(Compiler.class);
|
||||
|
||||
// ----------------------------------------------------- Instance Variables
|
||||
|
||||
protected JspCompilationContext ctxt;
|
||||
|
||||
protected ErrorDispatcher errDispatcher;
|
||||
|
||||
protected PageInfo pageInfo;
|
||||
|
||||
protected JspServletWrapper jsw;
|
||||
|
||||
protected TagFileProcessor tfp;
|
||||
|
||||
protected Options options;
|
||||
|
||||
protected Node.Nodes pageNodes;
|
||||
|
||||
// ------------------------------------------------------------ Constructor
|
||||
|
||||
public void init(JspCompilationContext ctxt, JspServletWrapper jsw) {
|
||||
this.jsw = jsw;
|
||||
this.ctxt = ctxt;
|
||||
this.options = ctxt.getOptions();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------- Public Methods
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Retrieves the parsed nodes of the JSP page, if they are available. May
|
||||
* return null. Used in development mode for generating detailed error
|
||||
* messages. http://issues.apache.org/bugzilla/show_bug.cgi?id=37062.
|
||||
* </p>
|
||||
*
|
||||
* @return page nodes
|
||||
*/
|
||||
public Node.Nodes getPageNodes() {
|
||||
return this.pageNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the jsp file into equivalent servlet in .java file
|
||||
*
|
||||
* @return a smap for the current JSP page, if one is generated, null
|
||||
* otherwise
|
||||
* @throws Exception in case of any errors
|
||||
*/
|
||||
protected String[] generateJava() throws Exception {
|
||||
|
||||
String[] smapStr = null;
|
||||
|
||||
long t1, t2, t3, t4;
|
||||
|
||||
t1 = t2 = t3 = t4 = 0;
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
t1 = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// Setup page info area
|
||||
pageInfo = new PageInfo(new BeanRepository(ctxt.getClassLoader(),
|
||||
errDispatcher), ctxt.getJspFile());
|
||||
|
||||
JspConfig jspConfig = options.getJspConfig();
|
||||
JspConfig.JspProperty jspProperty = jspConfig.findJspProperty(ctxt
|
||||
.getJspFile());
|
||||
|
||||
/*
|
||||
* If the current uri is matched by a pattern specified in a
|
||||
* jsp-property-group in web.xml, initialize pageInfo with those
|
||||
* properties.
|
||||
*/
|
||||
if (jspProperty.isELIgnored() != null) {
|
||||
pageInfo.setELIgnored(JspUtil.booleanValue(jspProperty
|
||||
.isELIgnored()));
|
||||
}
|
||||
if (jspProperty.isScriptingInvalid() != null) {
|
||||
pageInfo.setScriptingInvalid(JspUtil.booleanValue(jspProperty
|
||||
.isScriptingInvalid()));
|
||||
}
|
||||
if (jspProperty.getIncludePrelude() != null) {
|
||||
pageInfo.setIncludePrelude(jspProperty.getIncludePrelude());
|
||||
}
|
||||
if (jspProperty.getIncludeCoda() != null) {
|
||||
pageInfo.setIncludeCoda(jspProperty.getIncludeCoda());
|
||||
}
|
||||
if (jspProperty.isDeferedSyntaxAllowedAsLiteral() != null) {
|
||||
pageInfo.setDeferredSyntaxAllowedAsLiteral(JspUtil.booleanValue(jspProperty
|
||||
.isDeferedSyntaxAllowedAsLiteral()));
|
||||
}
|
||||
if (jspProperty.isTrimDirectiveWhitespaces() != null) {
|
||||
pageInfo.setTrimDirectiveWhitespaces(JspUtil.booleanValue(jspProperty
|
||||
.isTrimDirectiveWhitespaces()));
|
||||
}
|
||||
|
||||
ctxt.checkOutputDir();
|
||||
String javaFileName = ctxt.getServletJavaFileName();
|
||||
|
||||
ServletWriter writer = null;
|
||||
try {
|
||||
/*
|
||||
* The setting of isELIgnored changes the behaviour of the parser
|
||||
* in subtle ways. To add to the 'fun', isELIgnored can be set in
|
||||
* any file that forms part of the translation unit so setting it
|
||||
* in a file included towards the end of the translation unit can
|
||||
* change how the parser should have behaved when parsing content
|
||||
* up to the point where isELIgnored was set. Arghh!
|
||||
* Previous attempts to hack around this have only provided partial
|
||||
* solutions. We now use two passes to parse the translation unit.
|
||||
* The first just parses the directives and the second parses the
|
||||
* whole translation unit once we know how isELIgnored has been set.
|
||||
* TODO There are some possible optimisations of this process.
|
||||
*/
|
||||
// Parse the file
|
||||
ParserController parserCtl = new ParserController(ctxt, this);
|
||||
|
||||
// Pass 1 - the directives
|
||||
Node.Nodes directives =
|
||||
parserCtl.parseDirectives(ctxt.getJspFile());
|
||||
Validator.validateDirectives(this, directives);
|
||||
|
||||
// Pass 2 - the whole translation unit
|
||||
pageNodes = parserCtl.parse(ctxt.getJspFile());
|
||||
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
|
||||
|
||||
if (ctxt.isPrototypeMode()) {
|
||||
// generate prototype .java file for the tag file
|
||||
writer = setupContextWriter(byteArrayOutputStream);
|
||||
Generator.generate(writer, this, pageNodes);
|
||||
writer.close();
|
||||
writer = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate and process attributes - don't re-validate the
|
||||
// directives we validated in pass 1
|
||||
Validator.validateExDirectives(this, pageNodes);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
t2 = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// Collect page info
|
||||
Collector.collect(this, pageNodes);
|
||||
|
||||
// Compile (if necessary) and load the tag files referenced in
|
||||
// this compilation unit.
|
||||
tfp = new TagFileProcessor();
|
||||
tfp.loadTagFiles(this, pageNodes);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
t3 = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// Determine which custom tag needs to declare which scripting vars
|
||||
ScriptingVariabler.set(pageNodes, errDispatcher);
|
||||
|
||||
// Optimizations by Tag Plugins
|
||||
TagPluginManager tagPluginManager = options.getTagPluginManager();
|
||||
tagPluginManager.apply(pageNodes, errDispatcher, pageInfo);
|
||||
|
||||
// Optimization: concatenate contiguous template texts.
|
||||
TextOptimizer.concatenate(this, pageNodes);
|
||||
|
||||
// Generate static function mapper codes.
|
||||
ELFunctionMapper.map(this, pageNodes);
|
||||
|
||||
// generate servlet .java file
|
||||
writer = setupContextWriter(byteArrayOutputStream);
|
||||
Generator.generate(writer, this, pageNodes);
|
||||
writer.close();
|
||||
writer = null;
|
||||
|
||||
// The writer is only used during the compile, dereference
|
||||
// it in the JspCompilationContext when done to allow it
|
||||
// to be GC'd and save memory.
|
||||
ctxt.setWriter(null);
|
||||
ctxt.setSourceCode(byteArrayOutputStream.toString());
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
t4 = System.currentTimeMillis();
|
||||
log.debug("Generated " + javaFileName + " total=" + (t4 - t1)
|
||||
+ " generate=" + (t4 - t3) + " validate=" + (t2 - t1));
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (writer != null) {
|
||||
try {
|
||||
writer.close();
|
||||
writer = null;
|
||||
} catch (Exception e1) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
// Remove the generated .java file
|
||||
new File(javaFileName).delete();
|
||||
throw e;
|
||||
} finally {
|
||||
if (writer != null) {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (Exception e2) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JSR45 Support
|
||||
if (!options.isSmapSuppressed()) {
|
||||
smapStr = SmapUtil.generateSmap(ctxt, pageNodes);
|
||||
}
|
||||
|
||||
// If any proto type .java and .class files was generated,
|
||||
// the prototype .java may have been replaced by the current
|
||||
// compilation (if the tag file is self referencing), but the
|
||||
// .class file need to be removed, to make sure that javac would
|
||||
// generate .class again from the new .java file just generated.
|
||||
tfp.removeProtoTypeFiles(ctxt.getClassFileName());
|
||||
|
||||
return smapStr;
|
||||
}
|
||||
|
||||
private ServletWriter setupContextWriter(OutputStream os)
|
||||
throws FileNotFoundException, JasperException {
|
||||
ServletWriter writer;
|
||||
// Setup the ServletWriter
|
||||
String javaEncoding = ctxt.getOptions().getJavaEncoding();
|
||||
OutputStreamWriter osw = null;
|
||||
|
||||
try {
|
||||
osw = new OutputStreamWriter(os, javaEncoding);
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
errDispatcher.jspError("jsp.error.needAlternateJavaEncoding",
|
||||
javaEncoding);
|
||||
}
|
||||
|
||||
writer = new ServletWriter(new PrintWriter(osw));
|
||||
ctxt.setWriter(writer);
|
||||
return writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the servlet from .java file to .class file
|
||||
*
|
||||
* @param smap string array
|
||||
* @throws FileNotFoundException is file was not found
|
||||
* @throws JasperException in case of jasper errors
|
||||
* @throws Exception in case of other errors
|
||||
*/
|
||||
protected abstract void generateClass(String[] smap)
|
||||
throws FileNotFoundException, JasperException, Exception;
|
||||
|
||||
/**
|
||||
* Compile the jsp file from the current engine context
|
||||
* @throws FileNotFoundException is file was not found
|
||||
* @throws JasperException in case of jasper errors
|
||||
* @throws Exception in case of other errors
|
||||
*/
|
||||
public void compile() throws FileNotFoundException, JasperException,
|
||||
Exception {
|
||||
compile(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the jsp file from the current engine context. As an side- effect,
|
||||
* tag files that are referenced by this page are also compiled.
|
||||
*
|
||||
* @param compileClass
|
||||
* If true, generate both .java and .class file If false,
|
||||
* generate only .java file
|
||||
* @throws FileNotFoundException is file was not found
|
||||
* @throws JasperException in case of jasper errors
|
||||
* @throws Exception in case of other errors
|
||||
*/
|
||||
public void compile(boolean compileClass) throws FileNotFoundException,
|
||||
JasperException, Exception {
|
||||
compile(compileClass, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the jsp file from the current engine context. As an side- effect,
|
||||
* tag files that are referenced by this page are also compiled.
|
||||
*
|
||||
* @param compileClass
|
||||
* If true, generate both .java and .class file If false,
|
||||
* generate only .java file
|
||||
* @param jspcMode
|
||||
* true if invoked from JspC, false otherwise
|
||||
* @throws FileNotFoundException is file was not found
|
||||
* @throws JasperException in case of jasper errors
|
||||
* @throws Exception in case of other errors
|
||||
*/
|
||||
public void compile(boolean compileClass, boolean jspcMode)
|
||||
throws FileNotFoundException, JasperException, Exception {
|
||||
if (errDispatcher == null) {
|
||||
this.errDispatcher = new ErrorDispatcher(jspcMode);
|
||||
}
|
||||
|
||||
try {
|
||||
String[] smap = generateJava();
|
||||
if (compileClass) {
|
||||
generateClass(smap);
|
||||
// Fix for bugzilla 41606
|
||||
// Set JspServletWrapper.servletClassLastModifiedTime after successful compile
|
||||
String targetFileName = ctxt.getClassFileName();
|
||||
if (targetFileName != null) {
|
||||
File targetFile = new File(targetFileName);
|
||||
if (targetFile.exists() && jsw != null) {
|
||||
jsw.setServletClassLastModifiedTime(targetFile.lastModified());
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (tfp != null && ctxt.isPrototypeMode()) {
|
||||
tfp.removeProtoTypeFiles(null);
|
||||
}
|
||||
// Make sure these object which are only used during the
|
||||
// generation and compilation of the JSP page get
|
||||
// dereferenced so that they can be GC'd and reduce the
|
||||
// memory footprint.
|
||||
tfp = null;
|
||||
errDispatcher = null;
|
||||
pageInfo = null;
|
||||
|
||||
// Only get rid of the pageNodes if in production.
|
||||
// In development mode, they are used for detailed
|
||||
// error messages.
|
||||
// http://issues.apache.org/bugzilla/show_bug.cgi?id=37062
|
||||
if (!this.options.getDevelopment()) {
|
||||
pageNodes = null;
|
||||
}
|
||||
|
||||
if (ctxt.getWriter() != null) {
|
||||
ctxt.getWriter().close();
|
||||
ctxt.setWriter(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a protected method intended to be overridden by subclasses of
|
||||
* Compiler. This is used by the compile method to do all the compilation.
|
||||
*
|
||||
* @return true if out dated
|
||||
*/
|
||||
public boolean isOutDated() {
|
||||
return isOutDated(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a compilation is necessary by checking the time stamp of the
|
||||
* JSP page with that of the corresponding .class or .java file. If the page
|
||||
* has dependencies, the check is also extended to its dependants, and so
|
||||
* on. This method can by overridden by a subclasses of Compiler.
|
||||
*
|
||||
* @param checkClass
|
||||
* If true, check against .class file, if false, check against
|
||||
* .java file.
|
||||
*
|
||||
* @return true if out dated
|
||||
*/
|
||||
public boolean isOutDated(boolean checkClass) {
|
||||
|
||||
String jsp = ctxt.getJspFile();
|
||||
|
||||
if (jsw != null
|
||||
&& (ctxt.getOptions().getModificationTestInterval() > 0)) {
|
||||
|
||||
if (jsw.getLastModificationTest()
|
||||
+ (ctxt.getOptions().getModificationTestInterval() * 1000) > System
|
||||
.currentTimeMillis()) {
|
||||
return false;
|
||||
} else {
|
||||
jsw.setLastModificationTest(System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
long jspRealLastModified = 0;
|
||||
try {
|
||||
URL jspUrl = ctxt.getResource(jsp);
|
||||
if (jspUrl == null) {
|
||||
ctxt.incrementRemoved();
|
||||
return false;
|
||||
}
|
||||
URLConnection uc = jspUrl.openConnection();
|
||||
if (uc instanceof JarURLConnection) {
|
||||
jspRealLastModified =
|
||||
((JarURLConnection) uc).getJarEntry().getTime();
|
||||
} else {
|
||||
jspRealLastModified = uc.getLastModified();
|
||||
}
|
||||
uc.getInputStream().close();
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
long targetLastModified = 0;
|
||||
File targetFile;
|
||||
|
||||
if (checkClass) {
|
||||
targetFile = new File(ctxt.getClassFileName());
|
||||
} else {
|
||||
targetFile = new File(ctxt.getServletJavaFileName());
|
||||
}
|
||||
|
||||
if (!targetFile.exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
targetLastModified = targetFile.lastModified();
|
||||
if (checkClass && jsw != null) {
|
||||
jsw.setServletClassLastModifiedTime(targetLastModified);
|
||||
}
|
||||
if (targetLastModified < jspRealLastModified) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Compiler: outdated: " + targetFile + " "
|
||||
+ targetLastModified);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// determine if source dependent files (e.g. includes using include
|
||||
// directives) have been changed.
|
||||
if (jsw == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List depends = jsw.getDependants();
|
||||
if (depends == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Object depend : depends) {
|
||||
String include = (String) depend;
|
||||
try {
|
||||
URL includeUrl = ctxt.getResource(include);
|
||||
if (includeUrl == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
URLConnection iuc = includeUrl.openConnection();
|
||||
long includeLastModified = 0;
|
||||
if (iuc instanceof JarURLConnection) {
|
||||
includeLastModified =
|
||||
((JarURLConnection) iuc).getJarEntry().getTime();
|
||||
} else {
|
||||
includeLastModified = iuc.getLastModified();
|
||||
}
|
||||
iuc.getInputStream().close();
|
||||
|
||||
if (includeLastModified > targetLastModified) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the error dispatcher.
|
||||
*/
|
||||
public ErrorDispatcher getErrorDispatcher() {
|
||||
return errDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the info about the page under compilation
|
||||
*/
|
||||
public PageInfo getPageInfo() {
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
public JspCompilationContext getCompilationContext() {
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove generated files
|
||||
*/
|
||||
public void removeGeneratedFiles() {
|
||||
try {
|
||||
String classFileName = ctxt.getClassFileName();
|
||||
if (classFileName != null) {
|
||||
File classFile = new File(classFileName);
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Deleting " + classFile);
|
||||
classFile.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Remove as much as possible, ignore possible exceptions
|
||||
}
|
||||
try {
|
||||
String javaFileName = ctxt.getServletJavaFileName();
|
||||
if (javaFileName != null) {
|
||||
File javaFile = new File(javaFileName);
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Deleting " + javaFile);
|
||||
javaFile.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Remove as much as possible, ignore possible exceptions
|
||||
}
|
||||
}
|
||||
|
||||
public void removeGeneratedClassFiles() {
|
||||
try {
|
||||
String classFileName = ctxt.getClassFileName();
|
||||
if (classFileName != null) {
|
||||
File classFile = new File(classFileName);
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Deleting " + classFile);
|
||||
classFile.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Remove as much as possible, ignore possible exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
-110
@@ -1,110 +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.struts2.jasper.compiler;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
|
||||
/**
|
||||
* Default implementation of ErrorHandler interface.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
*/
|
||||
class DefaultErrorHandler implements ErrorHandler {
|
||||
|
||||
/*
|
||||
* Processes the given JSP parse error.
|
||||
*
|
||||
* @param fname Name of the JSP file in which the parse error occurred
|
||||
* @param line Parse error line number
|
||||
* @param column Parse error column number
|
||||
* @param errMsg Parse error message
|
||||
* @param exception Parse exception
|
||||
*/
|
||||
public void jspError(String fname, int line, int column, String errMsg,
|
||||
Exception ex) throws JasperException {
|
||||
throw new JasperException(fname + "(" + line + "," + column + ")"
|
||||
+ " " + errMsg, ex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes the given JSP parse error.
|
||||
*
|
||||
* @param errMsg Parse error message
|
||||
* @param exception Parse exception
|
||||
*/
|
||||
public void jspError(String errMsg, Exception ex) throws JasperException {
|
||||
throw new JasperException(errMsg, ex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes the given javac compilation errors.
|
||||
*
|
||||
* @param details Array of JavacErrorDetail instances corresponding to the
|
||||
* compilation errors
|
||||
*/
|
||||
public void javacError(JavacErrorDetail[] details) throws JasperException {
|
||||
|
||||
if (details == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object[] args = null;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
for (int i=0; i < details.length; i++) {
|
||||
if (details[i].getJspBeginLineNumber() >= 0) {
|
||||
args = new Object[] {
|
||||
new Integer(details[i].getJspBeginLineNumber()),
|
||||
details[i].getJspFileName() };
|
||||
buf.append("\n\n");
|
||||
buf.append(Localizer.getMessage("jsp.error.single.line.number",
|
||||
args));
|
||||
buf.append("\n");
|
||||
buf.append(details[i].getErrorMessage());
|
||||
buf.append("\n");
|
||||
buf.append(details[i].getJspExtract());
|
||||
} else {
|
||||
args = new Object[] {
|
||||
new Integer(details[i].getJavaLineNumber()) };
|
||||
buf.append("\n\n");
|
||||
buf.append(Localizer.getMessage("jsp.error.java.line.number",
|
||||
args));
|
||||
buf.append("\n");
|
||||
buf.append(details[i].getErrorMessage());
|
||||
}
|
||||
}
|
||||
buf.append("\n\nStacktrace:");
|
||||
throw new JasperException(
|
||||
Localizer.getMessage("jsp.error.unable.compile") + ": " + buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the given javac error report and exception.
|
||||
*
|
||||
* @param errorReport Compilation error report
|
||||
* @param exception Compilation exception
|
||||
*/
|
||||
public void javacError(String errorReport, Exception exception)
|
||||
throws JasperException {
|
||||
|
||||
throw new JasperException(
|
||||
Localizer.getMessage("jsp.error.unable.compile"), exception);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,200 +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.struts2.jasper.compiler;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
|
||||
class Dumper {
|
||||
|
||||
static class DumpVisitor extends Node.Visitor {
|
||||
private int indent = 0;
|
||||
|
||||
private String getAttributes(Attributes attrs) {
|
||||
if (attrs == null)
|
||||
return "";
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i=0; i < attrs.getLength(); i++) {
|
||||
buf.append(" " + attrs.getQName(i) + "=\""
|
||||
+ attrs.getValue(i) + "\"");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private void printString(String str) {
|
||||
printIndent();
|
||||
System.out.print(str);
|
||||
}
|
||||
|
||||
private void printString(String prefix, String str, String suffix) {
|
||||
printIndent();
|
||||
if (str != null) {
|
||||
System.out.print(prefix + str + suffix);
|
||||
} else {
|
||||
System.out.print(prefix + suffix);
|
||||
}
|
||||
}
|
||||
|
||||
private void printAttributes(String prefix, Attributes attrs,
|
||||
String suffix) {
|
||||
printString(prefix, getAttributes(attrs), suffix);
|
||||
}
|
||||
|
||||
private void dumpBody(Node n) throws JasperException {
|
||||
Node.Nodes page = n.getBody();
|
||||
if (page != null) {
|
||||
// indent++;
|
||||
page.visit(this);
|
||||
// indent--;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(Node.PageDirective n) throws JasperException {
|
||||
printAttributes("<%@ page", n.getAttributes(), "%>");
|
||||
}
|
||||
|
||||
public void visit(Node.TaglibDirective n) throws JasperException {
|
||||
printAttributes("<%@ taglib", n.getAttributes(), "%>");
|
||||
}
|
||||
|
||||
public void visit(Node.IncludeDirective n) throws JasperException {
|
||||
printAttributes("<%@ include", n.getAttributes(), "%>");
|
||||
dumpBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.Comment n) throws JasperException {
|
||||
printString("<%--", n.getText(), "--%>");
|
||||
}
|
||||
|
||||
public void visit(Node.Declaration n) throws JasperException {
|
||||
printString("<%!", n.getText(), "%>");
|
||||
}
|
||||
|
||||
public void visit(Node.Expression n) throws JasperException {
|
||||
printString("<%=", n.getText(), "%>");
|
||||
}
|
||||
|
||||
public void visit(Node.Scriptlet n) throws JasperException {
|
||||
printString("<%", n.getText(), "%>");
|
||||
}
|
||||
|
||||
public void visit(Node.IncludeAction n) throws JasperException {
|
||||
printAttributes("<jsp:include", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:include>");
|
||||
}
|
||||
|
||||
public void visit(Node.ForwardAction n) throws JasperException {
|
||||
printAttributes("<jsp:forward", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:forward>");
|
||||
}
|
||||
|
||||
public void visit(Node.GetProperty n) throws JasperException {
|
||||
printAttributes("<jsp:getProperty", n.getAttributes(), "/>");
|
||||
}
|
||||
|
||||
public void visit(Node.SetProperty n) throws JasperException {
|
||||
printAttributes("<jsp:setProperty", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:setProperty>");
|
||||
}
|
||||
|
||||
public void visit(Node.UseBean n) throws JasperException {
|
||||
printAttributes("<jsp:useBean", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:useBean>");
|
||||
}
|
||||
|
||||
public void visit(Node.PlugIn n) throws JasperException {
|
||||
printAttributes("<jsp:plugin", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:plugin>");
|
||||
}
|
||||
|
||||
public void visit(Node.ParamsAction n) throws JasperException {
|
||||
printAttributes("<jsp:params", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:params>");
|
||||
}
|
||||
|
||||
public void visit(Node.ParamAction n) throws JasperException {
|
||||
printAttributes("<jsp:param", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:param>");
|
||||
}
|
||||
|
||||
public void visit(Node.NamedAttribute n) throws JasperException {
|
||||
printAttributes("<jsp:attribute", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:attribute>");
|
||||
}
|
||||
|
||||
public void visit(Node.JspBody n) throws JasperException {
|
||||
printAttributes("<jsp:body", n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</jsp:body>");
|
||||
}
|
||||
|
||||
public void visit(Node.ELExpression n) throws JasperException {
|
||||
printString( "${" + new String( n.getText() ) + "}" );
|
||||
}
|
||||
|
||||
public void visit(Node.CustomTag n) throws JasperException {
|
||||
printAttributes("<" + n.getQName(), n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</" + n.getQName() + ">");
|
||||
}
|
||||
|
||||
public void visit(Node.UninterpretedTag n) throws JasperException {
|
||||
String tag = n.getQName();
|
||||
printAttributes("<"+tag, n.getAttributes(), ">");
|
||||
dumpBody(n);
|
||||
printString("</" + tag + ">");
|
||||
}
|
||||
|
||||
public void visit(Node.TemplateText n) throws JasperException {
|
||||
printString(new String(n.getText()));
|
||||
}
|
||||
|
||||
private void printIndent() {
|
||||
for (int i=0; i < indent; i++) {
|
||||
System.out.print(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void dump(Node n) {
|
||||
try {
|
||||
n.accept(new DumpVisitor());
|
||||
} catch (JasperException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void dump(Node.Nodes page) {
|
||||
try {
|
||||
page.visit(new DumpVisitor());
|
||||
} catch (JasperException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-284
@@ -1,284 +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.struts2.jasper.compiler;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.servlet.jsp.tagext.FunctionInfo;
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
|
||||
/**
|
||||
* This class generates functions mappers for the EL expressions in the page.
|
||||
* Instead of a global mapper, a mapper is used for ecah call to EL
|
||||
* evaluator, thus avoiding the prefix overlapping and redefinition
|
||||
* issues.
|
||||
*
|
||||
* @author Kin-man Chung
|
||||
*/
|
||||
|
||||
public class ELFunctionMapper {
|
||||
private int currFunc = 0;
|
||||
StringBuffer ds; // Contains codes to initialize the functions mappers.
|
||||
StringBuffer ss; // Contains declarations of the functions mappers.
|
||||
|
||||
/**
|
||||
* Creates the functions mappers for all EL expressions in the JSP page.
|
||||
*
|
||||
* @param compiler Current compiler, mainly for accessing error dispatcher.
|
||||
* @param page The current compilation unit.
|
||||
*
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public static void map(Compiler compiler, Node.Nodes page)
|
||||
throws JasperException {
|
||||
|
||||
ELFunctionMapper map = new ELFunctionMapper();
|
||||
map.ds = new StringBuffer();
|
||||
map.ss = new StringBuffer();
|
||||
|
||||
page.visit(map.new ELFunctionVisitor());
|
||||
|
||||
// Append the declarations to the root node
|
||||
String ds = map.ds.toString();
|
||||
if (ds.length() > 0) {
|
||||
Node root = page.getRoot();
|
||||
new Node.Declaration(map.ss.toString(), null, root);
|
||||
new Node.Declaration("static {\n" + ds + "}\n", null, root);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor for the page. The places where EL is allowed are scanned
|
||||
* for functions, and if found functions mappers are created.
|
||||
*/
|
||||
class ELFunctionVisitor extends Node.Visitor {
|
||||
|
||||
/**
|
||||
* Use a global name map to facilitate reuse of function maps.
|
||||
* The key used is prefix:function:uri.
|
||||
*/
|
||||
private HashMap<String, String> gMap = new HashMap<String, String>();
|
||||
|
||||
public void visit(Node.ParamAction n) throws JasperException {
|
||||
doMap(n.getValue());
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.IncludeAction n) throws JasperException {
|
||||
doMap(n.getPage());
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.ForwardAction n) throws JasperException {
|
||||
doMap(n.getPage());
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.SetProperty n) throws JasperException {
|
||||
doMap(n.getValue());
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.UseBean n) throws JasperException {
|
||||
doMap(n.getBeanName());
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.PlugIn n) throws JasperException {
|
||||
doMap(n.getHeight());
|
||||
doMap(n.getWidth());
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.JspElement n) throws JasperException {
|
||||
|
||||
Node.JspAttribute[] attrs = n.getJspAttributes();
|
||||
for (int i = 0; attrs != null && i < attrs.length; i++) {
|
||||
doMap(attrs[i]);
|
||||
}
|
||||
doMap(n.getNameAttribute());
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.UninterpretedTag n) throws JasperException {
|
||||
|
||||
Node.JspAttribute[] attrs = n.getJspAttributes();
|
||||
for (int i = 0; attrs != null && i < attrs.length; i++) {
|
||||
doMap(attrs[i]);
|
||||
}
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.CustomTag n) throws JasperException {
|
||||
Node.JspAttribute[] attrs = n.getJspAttributes();
|
||||
for (int i = 0; attrs != null && i < attrs.length; i++) {
|
||||
doMap(attrs[i]);
|
||||
}
|
||||
visitBody(n);
|
||||
}
|
||||
|
||||
public void visit(Node.ELExpression n) throws JasperException {
|
||||
doMap(n.getEL());
|
||||
}
|
||||
|
||||
private void doMap(Node.JspAttribute attr)
|
||||
throws JasperException {
|
||||
if (attr != null) {
|
||||
doMap(attr.getEL());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates function mappers, if needed, from ELNodes
|
||||
*/
|
||||
private void doMap(ELNode.Nodes el)
|
||||
throws JasperException {
|
||||
|
||||
// Only care about functions in ELNode's
|
||||
class Fvisitor extends ELNode.Visitor {
|
||||
ArrayList<ELNode.Function> funcs =
|
||||
new ArrayList<ELNode.Function>();
|
||||
HashMap<String, String> keyMap = new HashMap<String, String>();
|
||||
public void visit(ELNode.Function n) throws JasperException {
|
||||
String key = n.getPrefix() + ":" + n.getName();
|
||||
if (! keyMap.containsKey(key)) {
|
||||
keyMap.put(key,"");
|
||||
funcs.add(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (el == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First locate all unique functions in this EL
|
||||
Fvisitor fv = new Fvisitor();
|
||||
el.visit(fv);
|
||||
ArrayList functions = fv.funcs;
|
||||
|
||||
if (functions.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reuse a previous map if possible
|
||||
String decName = matchMap(functions);
|
||||
if (decName != null) {
|
||||
el.setMapName(decName);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate declaration for the map statically
|
||||
decName = getMapName();
|
||||
ss.append("static private org.apache.struts2.jasper.runtime.ProtectedFunctionMapper " + decName + ";\n");
|
||||
|
||||
ds.append(" " + decName + "= ");
|
||||
ds.append("org.apache.struts2.jasper.runtime.ProtectedFunctionMapper");
|
||||
|
||||
// Special case if there is only one function in the map
|
||||
String funcMethod = null;
|
||||
if (functions.size() == 1) {
|
||||
funcMethod = ".getMapForFunction";
|
||||
} else {
|
||||
ds.append(".getInstance();\n");
|
||||
funcMethod = " " + decName + ".mapFunction";
|
||||
}
|
||||
|
||||
// Setup arguments for either getMapForFunction or mapFunction
|
||||
for (int i = 0; i < functions.size(); i++) {
|
||||
ELNode.Function f = (ELNode.Function)functions.get(i);
|
||||
FunctionInfo funcInfo = f.getFunctionInfo();
|
||||
String key = f.getPrefix()+ ":" + f.getName();
|
||||
ds.append(funcMethod + "(\"" + key + "\", " +
|
||||
funcInfo.getFunctionClass() + ".class, " +
|
||||
'\"' + f.getMethodName() + "\", " +
|
||||
"new Class[] {");
|
||||
String params[] = f.getParameters();
|
||||
for (int k = 0; k < params.length; k++) {
|
||||
if (k != 0) {
|
||||
ds.append(", ");
|
||||
}
|
||||
int iArray = params[k].indexOf('[');
|
||||
if (iArray < 0) {
|
||||
ds.append(params[k] + ".class");
|
||||
}
|
||||
else {
|
||||
String baseType = params[k].substring(0, iArray);
|
||||
ds.append("java.lang.reflect.Array.newInstance(");
|
||||
ds.append(baseType);
|
||||
ds.append(".class,");
|
||||
|
||||
// Count the number of array dimension
|
||||
int aCount = 0;
|
||||
for (int jj = iArray; jj < params[k].length(); jj++ ) {
|
||||
if (params[k].charAt(jj) == '[') {
|
||||
aCount++;
|
||||
}
|
||||
}
|
||||
if (aCount == 1) {
|
||||
ds.append("0).getClass()");
|
||||
} else {
|
||||
ds.append("new int[" + aCount + "]).getClass()");
|
||||
}
|
||||
}
|
||||
}
|
||||
ds.append("});\n");
|
||||
// Put the current name in the global function map
|
||||
gMap.put(f.getPrefix() + ':' + f.getName() + ':' + f.getUri(),
|
||||
decName);
|
||||
}
|
||||
el.setMapName(decName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the name of the function mapper for an EL. Reuse a
|
||||
* previously generated one if possible.
|
||||
* @param functions An ArrayList of ELNode.Function instances that
|
||||
* represents the functions in an EL
|
||||
* @return A previous generated function mapper name that can be used
|
||||
* by this EL; null if none found.
|
||||
*/
|
||||
private String matchMap(ArrayList functions) {
|
||||
|
||||
String mapName = null;
|
||||
for (int i = 0; i < functions.size(); i++) {
|
||||
ELNode.Function f = (ELNode.Function)functions.get(i);
|
||||
String temName = (String) gMap.get(f.getPrefix() + ':' +
|
||||
f.getName() + ':' + f.getUri());
|
||||
if (temName == null) {
|
||||
return null;
|
||||
}
|
||||
if (mapName == null) {
|
||||
mapName = temName;
|
||||
} else if (!temName.equals(mapName)) {
|
||||
// If not all in the previous match, then no match.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return mapName;
|
||||
}
|
||||
|
||||
/*
|
||||
* @return An unique name for a function mapper.
|
||||
*/
|
||||
private String getMapName() {
|
||||
return "_jspx_fnmap_" + currFunc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,256 +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.struts2.jasper.compiler;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.servlet.jsp.tagext.FunctionInfo;
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
|
||||
/**
|
||||
* This class defines internal representation for an EL Expression
|
||||
*
|
||||
* It currently only defines functions. It can be expanded to define
|
||||
* all the components of an EL expression, if need to.
|
||||
*
|
||||
* @author Kin-man Chung
|
||||
*/
|
||||
|
||||
abstract class ELNode {
|
||||
|
||||
abstract public void accept(Visitor v) throws JasperException;
|
||||
|
||||
/**
|
||||
* Child classes
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Represents an EL expression: anything in ${ and }.
|
||||
*/
|
||||
public static class Root extends ELNode {
|
||||
|
||||
private ELNode.Nodes expr;
|
||||
private char type;
|
||||
|
||||
Root(ELNode.Nodes expr, char type) {
|
||||
this.expr = expr;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void accept(Visitor v) throws JasperException {
|
||||
v.visit(this);
|
||||
}
|
||||
|
||||
public ELNode.Nodes getExpression() {
|
||||
return expr;
|
||||
}
|
||||
|
||||
public char getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents text outside of EL expression.
|
||||
*/
|
||||
public static class Text extends ELNode {
|
||||
|
||||
private String text;
|
||||
|
||||
Text(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void accept(Visitor v) throws JasperException {
|
||||
v.visit(this);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents anything in EL expression, other than functions, including
|
||||
* function arguments etc
|
||||
*/
|
||||
public static class ELText extends ELNode {
|
||||
|
||||
private String text;
|
||||
|
||||
ELText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void accept(Visitor v) throws JasperException {
|
||||
v.visit(this);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a function
|
||||
* Currently only include the prefix and function name, but not its
|
||||
* arguments.
|
||||
*/
|
||||
public static class Function extends ELNode {
|
||||
|
||||
private String prefix;
|
||||
private String name;
|
||||
private String uri;
|
||||
private FunctionInfo functionInfo;
|
||||
private String methodName;
|
||||
private String[] parameters;
|
||||
|
||||
Function(String prefix, String name) {
|
||||
this.prefix = prefix;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void accept(Visitor v) throws JasperException {
|
||||
v.visit(this);
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public void setFunctionInfo(FunctionInfo f) {
|
||||
this.functionInfo = f;
|
||||
}
|
||||
|
||||
public FunctionInfo getFunctionInfo() {
|
||||
return functionInfo;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public void setParameters(String[] parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public String[] getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An ordered list of ELNode.
|
||||
*/
|
||||
public static class Nodes {
|
||||
|
||||
/* Name used for creating a map for the functions in this
|
||||
EL expression, for communication to Generator.
|
||||
*/
|
||||
String mapName = null; // The function map associated this EL
|
||||
private List<ELNode> list;
|
||||
|
||||
public Nodes() {
|
||||
list = new ArrayList<ELNode>();
|
||||
}
|
||||
|
||||
public void add(ELNode en) {
|
||||
list.add(en);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit the nodes in the list with the supplied visitor
|
||||
* @param v The visitor used
|
||||
*/
|
||||
public void visit(Visitor v) throws JasperException {
|
||||
Iterator<ELNode> iter = list.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ELNode n = iter.next();
|
||||
n.accept(v);
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator<ELNode> iterator() {
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return list.size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the expression contains a ${...}
|
||||
*/
|
||||
public boolean containsEL() {
|
||||
Iterator<ELNode> iter = list.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ELNode n = iter.next();
|
||||
if (n instanceof Root) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setMapName(String name) {
|
||||
this.mapName = name;
|
||||
}
|
||||
|
||||
public String getMapName() {
|
||||
return mapName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* A visitor class for traversing ELNodes
|
||||
*/
|
||||
public static class Visitor {
|
||||
|
||||
public void visit(Root n) throws JasperException {
|
||||
n.getExpression().visit(this);
|
||||
}
|
||||
|
||||
public void visit(Function n) throws JasperException {
|
||||
}
|
||||
|
||||
public void visit(Text n) throws JasperException {
|
||||
}
|
||||
|
||||
public void visit(ELText n) throws JasperException {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,383 +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.struts2.jasper.compiler;
|
||||
|
||||
/**
|
||||
* This class implements a parser for EL expressions.
|
||||
*
|
||||
* It takes strings of the form xxx${..}yyy${..}zzz etc, and turn it into a
|
||||
* ELNode.Nodes.
|
||||
*
|
||||
* Currently, it only handles text outside ${..} and functions in ${ ..}.
|
||||
*
|
||||
* @author Kin-man Chung
|
||||
*/
|
||||
|
||||
public class ELParser {
|
||||
|
||||
private Token curToken; // current token
|
||||
|
||||
private ELNode.Nodes expr;
|
||||
|
||||
private ELNode.Nodes ELexpr;
|
||||
|
||||
private int index; // Current index of the expression
|
||||
|
||||
private String expression; // The EL expression
|
||||
|
||||
private char type;
|
||||
|
||||
private boolean escapeBS; // is '\' an escape char in text outside EL?
|
||||
|
||||
private static final String reservedWords[] = { "and", "div", "empty",
|
||||
"eq", "false", "ge", "gt", "instanceof", "le", "lt", "mod", "ne",
|
||||
"not", "null", "or", "true" };
|
||||
|
||||
public ELParser(String expression) {
|
||||
index = 0;
|
||||
this.expression = expression;
|
||||
expr = new ELNode.Nodes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an EL expression
|
||||
*
|
||||
* @param expression
|
||||
* The input expression string of the form Char* ('${' Char*
|
||||
* '}')* Char*
|
||||
* @return Parsed EL expression in ELNode.Nodes
|
||||
*/
|
||||
public static ELNode.Nodes parse(String expression) {
|
||||
ELParser parser = new ELParser(expression);
|
||||
while (parser.hasNextChar()) {
|
||||
String text = parser.skipUntilEL();
|
||||
if (text.length() > 0) {
|
||||
parser.expr.add(new ELNode.Text(text));
|
||||
}
|
||||
ELNode.Nodes elexpr = parser.parseEL();
|
||||
if (!elexpr.isEmpty()) {
|
||||
parser.expr.add(new ELNode.Root(elexpr, parser.type));
|
||||
}
|
||||
}
|
||||
return parser.expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an EL expression string '${...}'
|
||||
*
|
||||
* @return An ELNode.Nodes representing the EL expression TODO: Currently
|
||||
* only parsed into functions and text strings. This should be
|
||||
* rewritten for a full parser.
|
||||
*/
|
||||
private ELNode.Nodes parseEL() {
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
ELexpr = new ELNode.Nodes();
|
||||
while (hasNext()) {
|
||||
curToken = nextToken();
|
||||
if (curToken instanceof Char) {
|
||||
if (curToken.toChar() == '}') {
|
||||
break;
|
||||
}
|
||||
buf.append(curToken.toChar());
|
||||
} else {
|
||||
// Output whatever is in buffer
|
||||
if (buf.length() > 0) {
|
||||
ELexpr.add(new ELNode.ELText(buf.toString()));
|
||||
}
|
||||
if (!parseFunction()) {
|
||||
ELexpr.add(new ELNode.ELText(curToken.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf.length() > 0) {
|
||||
ELexpr.add(new ELNode.ELText(buf.toString()));
|
||||
}
|
||||
|
||||
return ELexpr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse for a function FunctionInvokation ::= (identifier ':')? identifier
|
||||
* '(' (Expression (,Expression)*)? ')' Note: currently we don't parse
|
||||
* arguments
|
||||
*/
|
||||
private boolean parseFunction() {
|
||||
if (!(curToken instanceof Id) || isELReserved(curToken.toString())) {
|
||||
return false;
|
||||
}
|
||||
String s1 = null; // Function prefix
|
||||
String s2 = curToken.toString(); // Function name
|
||||
int mark = getIndex();
|
||||
if (hasNext()) {
|
||||
Token t = nextToken();
|
||||
if (t.toChar() == ':') {
|
||||
if (hasNext()) {
|
||||
Token t2 = nextToken();
|
||||
if (t2 instanceof Id) {
|
||||
s1 = s2;
|
||||
s2 = t2.toString();
|
||||
if (hasNext()) {
|
||||
t = nextToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (t.toChar() == '(') {
|
||||
ELexpr.add(new ELNode.Function(s1, s2));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
setIndex(mark);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if an id is a reserved word in EL
|
||||
*/
|
||||
private boolean isELReserved(String id) {
|
||||
int i = 0;
|
||||
int j = reservedWords.length;
|
||||
while (i < j) {
|
||||
int k = (i + j) / 2;
|
||||
int result = reservedWords[k].compareTo(id);
|
||||
if (result == 0) {
|
||||
return true;
|
||||
}
|
||||
if (result < 0) {
|
||||
i = k + 1;
|
||||
} else {
|
||||
j = k;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip until an EL expression ('${' || '#{') is reached, allowing escape
|
||||
* sequences '\\' and '\$' and '\#'.
|
||||
*
|
||||
* @return The text string up to the EL expression
|
||||
*/
|
||||
private String skipUntilEL() {
|
||||
char prev = 0;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
while (hasNextChar()) {
|
||||
char ch = nextChar();
|
||||
if (prev == '\\') {
|
||||
prev = 0;
|
||||
if (ch == '\\') {
|
||||
buf.append('\\');
|
||||
if (!escapeBS)
|
||||
prev = '\\';
|
||||
} else if (ch == '$' || ch == '#') {
|
||||
buf.append(ch);
|
||||
}
|
||||
// else error!
|
||||
} else if (prev == '$' || prev == '#') {
|
||||
if (ch == '{') {
|
||||
this.type = prev;
|
||||
prev = 0;
|
||||
break;
|
||||
}
|
||||
buf.append(prev);
|
||||
prev = 0;
|
||||
}
|
||||
if (ch == '\\' || ch == '$' || ch == '#') {
|
||||
prev = ch;
|
||||
} else {
|
||||
buf.append(ch);
|
||||
}
|
||||
}
|
||||
if (prev != 0) {
|
||||
buf.append(prev);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* @return true if there is something left in EL expression buffer other
|
||||
* than white spaces.
|
||||
*/
|
||||
private boolean hasNext() {
|
||||
skipSpaces();
|
||||
return hasNextChar();
|
||||
}
|
||||
|
||||
/*
|
||||
* @return The next token in the EL expression buffer.
|
||||
*/
|
||||
private Token nextToken() {
|
||||
skipSpaces();
|
||||
if (hasNextChar()) {
|
||||
char ch = nextChar();
|
||||
if (Character.isJavaIdentifierStart(ch)) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(ch);
|
||||
while ((ch = peekChar()) != -1
|
||||
&& Character.isJavaIdentifierPart(ch)) {
|
||||
buf.append(ch);
|
||||
nextChar();
|
||||
}
|
||||
return new Id(buf.toString());
|
||||
}
|
||||
|
||||
if (ch == '\'' || ch == '"') {
|
||||
return parseQuotedChars(ch);
|
||||
} else {
|
||||
// For now...
|
||||
return new Char(ch);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a string in single or double quotes, allowing for escape sequences
|
||||
* '\\', and ('\"', or "\'")
|
||||
*/
|
||||
private Token parseQuotedChars(char quote) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(quote);
|
||||
while (hasNextChar()) {
|
||||
char ch = nextChar();
|
||||
if (ch == '\\') {
|
||||
ch = nextChar();
|
||||
if (ch == '\\' || ch == quote) {
|
||||
buf.append(ch);
|
||||
}
|
||||
// else error!
|
||||
} else if (ch == quote) {
|
||||
buf.append(ch);
|
||||
break;
|
||||
} else {
|
||||
buf.append(ch);
|
||||
}
|
||||
}
|
||||
return new QuotedString(buf.toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* A collection of low level parse methods dealing with character in the EL
|
||||
* expression buffer.
|
||||
*/
|
||||
|
||||
private void skipSpaces() {
|
||||
while (hasNextChar()) {
|
||||
if (expression.charAt(index) > ' ')
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasNextChar() {
|
||||
return index < expression.length();
|
||||
}
|
||||
|
||||
private char nextChar() {
|
||||
if (index >= expression.length()) {
|
||||
return (char) -1;
|
||||
}
|
||||
return expression.charAt(index++);
|
||||
}
|
||||
|
||||
private char peekChar() {
|
||||
if (index >= expression.length()) {
|
||||
return (char) -1;
|
||||
}
|
||||
return expression.charAt(index);
|
||||
}
|
||||
|
||||
private int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
private void setIndex(int i) {
|
||||
index = i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Represents a token in EL expression string
|
||||
*/
|
||||
private static class Token {
|
||||
|
||||
char toChar() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Represents an ID token in EL
|
||||
*/
|
||||
private static class Id extends Token {
|
||||
String id;
|
||||
|
||||
Id(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Represents a character token in EL
|
||||
*/
|
||||
private static class Char extends Token {
|
||||
|
||||
private char ch;
|
||||
|
||||
Char(char ch) {
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
char toChar() {
|
||||
return ch;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (new Character(ch)).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Represents a quoted (single or double) string token in EL
|
||||
*/
|
||||
private static class QuotedString extends Token {
|
||||
|
||||
private String value;
|
||||
|
||||
QuotedString(String v) {
|
||||
this.value = v;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public char getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
-699
@@ -1,699 +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.struts2.jasper.compiler;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
import org.apache.struts2.jasper.JspCompilationContext;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Class responsible for dispatching JSP parse and javac compilation errors
|
||||
* to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This class is also responsible for localizing any error codes before they
|
||||
* are passed on to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* In the case of a Java compilation error, the compiler error message is
|
||||
* parsed into an array of JavacErrorDetail instances, which is passed on to
|
||||
* the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* @author Jan Luehe
|
||||
* @author Kin-man Chung
|
||||
*/
|
||||
public class ErrorDispatcher {
|
||||
|
||||
// Custom error handler
|
||||
private ErrorHandler errHandler;
|
||||
|
||||
// Indicates whether the compilation was initiated by JspServlet or JspC
|
||||
private boolean jspcMode = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param jspcMode true if compilation has been initiated by JspC, false otherwise
|
||||
*/
|
||||
public ErrorDispatcher(boolean jspcMode) {
|
||||
// XXX check web.xml for custom error handler
|
||||
errHandler = new DefaultErrorHandler();
|
||||
this.jspcMode = jspcMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param errCode Error code
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(String errCode) throws JasperException {
|
||||
dispatch(null, errCode, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
* @param where Error location
|
||||
* @param errCode Error code
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Mark where, String errCode) throws JasperException {
|
||||
dispatch(where, errCode, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param n Node that caused the error
|
||||
* @param errCode Error code
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Node n, String errCode) throws JasperException {
|
||||
dispatch(n.getStart(), errCode, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param errCode Error code
|
||||
* @param arg Argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(String errCode, String arg) throws JasperException {
|
||||
dispatch(null, errCode, new Object[]{arg}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param where Error location
|
||||
* @param errCode Error code
|
||||
* @param arg Argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Mark where, String errCode, String arg)
|
||||
throws JasperException {
|
||||
dispatch(where, errCode, new Object[]{arg}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param n Node that caused the error
|
||||
* @param errCode Error code
|
||||
* @param arg Argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Node n, String errCode, String arg)
|
||||
throws JasperException {
|
||||
dispatch(n.getStart(), errCode, new Object[]{arg}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param errCode Error code
|
||||
* @param arg1 First argument for parametric replacement
|
||||
* @param arg2 Second argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(String errCode, String arg1, String arg2)
|
||||
throws JasperException {
|
||||
dispatch(null, errCode, new Object[]{arg1, arg2}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param errCode Error code
|
||||
* @param arg1 First argument for parametric replacement
|
||||
* @param arg2 Second argument for parametric replacement
|
||||
* @param arg3 Third argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(String errCode, String arg1, String arg2, String arg3)
|
||||
throws JasperException {
|
||||
dispatch(null, errCode, new Object[]{arg1, arg2, arg3}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param where Error location
|
||||
* @param errCode Error code
|
||||
* @param arg1 First argument for parametric replacement
|
||||
* @param arg2 Second argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Mark where, String errCode, String arg1, String arg2)
|
||||
throws JasperException {
|
||||
dispatch(where, errCode, new Object[]{arg1, arg2}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param where Error location
|
||||
* @param errCode Error code
|
||||
* @param arg1 First argument for parametric replacement
|
||||
* @param arg2 Second argument for parametric replacement
|
||||
* @param arg3 Third argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Mark where, String errCode, String arg1, String arg2,
|
||||
String arg3)
|
||||
throws JasperException {
|
||||
dispatch(where, errCode, new Object[]{arg1, arg2, arg3}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param n Node that caused the error
|
||||
* @param errCode Error code
|
||||
* @param arg1 First argument for parametric replacement
|
||||
* @param arg2 Second argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Node n, String errCode, String arg1, String arg2)
|
||||
throws JasperException {
|
||||
dispatch(n.getStart(), errCode, new Object[]{arg1, arg2}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param n Node that caused the error
|
||||
* @param errCode Error code
|
||||
* @param arg1 First argument for parametric replacement
|
||||
* @param arg2 Second argument for parametric replacement
|
||||
* @param arg3 Third argument for parametric replacement
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Node n, String errCode, String arg1, String arg2,
|
||||
String arg3)
|
||||
throws JasperException {
|
||||
dispatch(n.getStart(), errCode, new Object[]{arg1, arg2, arg3}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given parsing exception to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* @param e Parsing exception
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Exception e) throws JasperException {
|
||||
dispatch(null, null, null, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param errCode Error code
|
||||
* @param arg Argument for parametric replacement
|
||||
* @param e Parsing exception
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(String errCode, String arg, Exception e)
|
||||
throws JasperException {
|
||||
dispatch(null, errCode, new Object[]{arg}, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
* </p>
|
||||
*
|
||||
* @param n Node that caused the error
|
||||
* @param errCode Error code
|
||||
* @param arg Argument for parametric replacement
|
||||
* @param e Parsing exception
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(Node n, String errCode, String arg, Exception e)
|
||||
throws JasperException {
|
||||
dispatch(n.getStart(), errCode, new Object[]{arg}, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Parses the given error message into an array of javac compilation error
|
||||
* messages (one per javac compilation error line number).
|
||||
* </p>
|
||||
*
|
||||
* @param errMsg Error message
|
||||
* @param fname Name of Java source file whose compilation failed
|
||||
* @param page Node representation of JSP page from which the Java source
|
||||
* file was generated
|
||||
* @return Array of javac compilation errors, or null if the given error
|
||||
* message does not contain any compilation error line numbers
|
||||
* @throws JasperException in case of Jasper errors
|
||||
* @throws IOException in case of IO errors
|
||||
*/
|
||||
public static JavacErrorDetail[] parseJavacErrors(String errMsg,
|
||||
String fname,
|
||||
Node.Nodes page)
|
||||
throws JasperException, IOException {
|
||||
|
||||
return parseJavacMessage(errMsg, fname, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given javac compilation errors to the configured error
|
||||
* handler.
|
||||
* </p>
|
||||
*
|
||||
* @param javacErrors Array of javac compilation errors
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void javacError(JavacErrorDetail[] javacErrors)
|
||||
throws JasperException {
|
||||
|
||||
errHandler.javacError(javacErrors);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Dispatches the given compilation error report and exception to the
|
||||
* configured error handler.
|
||||
* </p>
|
||||
*
|
||||
* @param errorReport Compilation error report
|
||||
* @param e Compilation exception
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void javacError(String errorReport, Exception e)
|
||||
throws JasperException {
|
||||
|
||||
errHandler.javacError(errorReport, e);
|
||||
}
|
||||
|
||||
|
||||
//*********************************************************************
|
||||
// Private utility methods
|
||||
|
||||
/*
|
||||
* Dispatches the given JSP parse error to the configured error handler.
|
||||
*
|
||||
* The given error code is localized. If it is not found in the
|
||||
* resource bundle for localized error messages, it is used as the error
|
||||
* message.
|
||||
*
|
||||
* @param where Error location
|
||||
* @param errCode Error code
|
||||
* @param args Arguments for parametric replacement
|
||||
* @param e Parsing exception
|
||||
*/
|
||||
private void dispatch(Mark where, String errCode, Object[] args,
|
||||
Exception e) throws JasperException {
|
||||
String file = null;
|
||||
String errMsg = null;
|
||||
int line = -1;
|
||||
int column = -1;
|
||||
boolean hasLocation = false;
|
||||
|
||||
// Localize
|
||||
if (errCode != null) {
|
||||
errMsg = Localizer.getMessage(errCode, args);
|
||||
} else if (e != null) {
|
||||
// give a hint about what's wrong
|
||||
errMsg = e.getMessage();
|
||||
}
|
||||
|
||||
// Get error location
|
||||
if (where != null) {
|
||||
if (jspcMode) {
|
||||
// Get the full URL of the resource that caused the error
|
||||
try {
|
||||
file = where.getURL().toString();
|
||||
} catch (MalformedURLException me) {
|
||||
// Fallback to using context-relative path
|
||||
file = where.getFile();
|
||||
}
|
||||
} else {
|
||||
// Get the context-relative resource path, so as to not
|
||||
// disclose any local filesystem details
|
||||
file = where.getFile();
|
||||
}
|
||||
line = where.getLineNumber();
|
||||
column = where.getColumnNumber();
|
||||
hasLocation = true;
|
||||
}
|
||||
// Get nested exception
|
||||
Exception nestedEx = e;
|
||||
if ((e instanceof SAXException)
|
||||
&& (((SAXException) e).getException() != null)) {
|
||||
nestedEx = ((SAXException) e).getException();
|
||||
}
|
||||
|
||||
if (hasLocation) {
|
||||
errHandler.jspError(file, line, column, errMsg, nestedEx);
|
||||
} else {
|
||||
errHandler.jspError(errMsg, nestedEx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses the given Java compilation error message, which may contain one
|
||||
* or more compilation errors, into an array of JavacErrorDetail instances.
|
||||
*
|
||||
* Each JavacErrorDetail instance contains the information about a single
|
||||
* compilation error.
|
||||
*
|
||||
* @param errMsg Compilation error message that was generated by the
|
||||
* javac compiler
|
||||
* @param fname Name of Java source file whose compilation failed
|
||||
* @param page Node representation of JSP page from which the Java source
|
||||
* file was generated
|
||||
*
|
||||
* @return Array of JavacErrorDetail instances corresponding to the
|
||||
* compilation errors
|
||||
*/
|
||||
private static JavacErrorDetail[] parseJavacMessage(
|
||||
String errMsg, String fname, Node.Nodes page)
|
||||
throws IOException, JasperException {
|
||||
|
||||
ArrayList<JavacErrorDetail> errors = new ArrayList<JavacErrorDetail>();
|
||||
StringBuffer errMsgBuf = null;
|
||||
int lineNum = -1;
|
||||
JavacErrorDetail javacError = null;
|
||||
|
||||
BufferedReader reader = new BufferedReader(new StringReader(errMsg));
|
||||
|
||||
/*
|
||||
* Parse compilation errors. Each compilation error consists of a file
|
||||
* path and error line number, followed by a number of lines describing
|
||||
* the error.
|
||||
*/
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
|
||||
/*
|
||||
* Error line number is delimited by set of colons.
|
||||
* Ignore colon following drive letter on Windows (fromIndex = 2).
|
||||
* XXX Handle deprecation warnings that don't have line info
|
||||
*/
|
||||
int beginColon = line.indexOf(':', 2);
|
||||
int endColon = line.indexOf(':', beginColon + 1);
|
||||
if ((beginColon >= 0) && (endColon >= 0)) {
|
||||
if (javacError != null) {
|
||||
// add previous error to error vector
|
||||
errors.add(javacError);
|
||||
}
|
||||
|
||||
String lineNumStr = line.substring(beginColon + 1, endColon);
|
||||
try {
|
||||
lineNum = Integer.parseInt(lineNumStr);
|
||||
} catch (NumberFormatException e) {
|
||||
lineNum = -1;
|
||||
}
|
||||
|
||||
errMsgBuf = new StringBuffer();
|
||||
|
||||
javacError = createJavacError(fname, page, errMsgBuf, lineNum);
|
||||
}
|
||||
|
||||
// Ignore messages preceding first error
|
||||
if (errMsgBuf != null) {
|
||||
errMsgBuf.append(line);
|
||||
errMsgBuf.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Add last error to error vector
|
||||
if (javacError != null) {
|
||||
errors.add(javacError);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
|
||||
JavacErrorDetail[] errDetails = null;
|
||||
if (errors.size() > 0) {
|
||||
errDetails = new JavacErrorDetail[errors.size()];
|
||||
errors.toArray(errDetails);
|
||||
}
|
||||
|
||||
return errDetails;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param fname Name of the JSP file in which the parse error occurred
|
||||
* @param page page
|
||||
* @param errMsgBuf error message buffer
|
||||
* @param lineNum line number
|
||||
* @return JavacErrorDetail The error details
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public static JavacErrorDetail createJavacError(String fname,
|
||||
Node.Nodes page, StringBuffer errMsgBuf, int lineNum)
|
||||
throws JasperException {
|
||||
return createJavacError(fname, page, errMsgBuf, lineNum, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param fname Name of the JSP file in which the parse error occurred
|
||||
* @param page page
|
||||
* @param errMsgBuf error message buffer
|
||||
* @param lineNum line number
|
||||
* @param ctxt JSP compilation context
|
||||
* @return JavacErrorDetail The error details
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public static JavacErrorDetail createJavacError(String fname,
|
||||
Node.Nodes page, StringBuffer errMsgBuf, int lineNum,
|
||||
JspCompilationContext ctxt) throws JasperException {
|
||||
JavacErrorDetail javacError;
|
||||
// Attempt to map javac error line number to line in JSP page
|
||||
ErrorVisitor errVisitor = new ErrorVisitor(lineNum);
|
||||
page.visit(errVisitor);
|
||||
Node errNode = errVisitor.getJspSourceNode();
|
||||
if ((errNode != null) && (errNode.getStart() != null)) {
|
||||
// If this is a scriplet node then there is a one to one mapping
|
||||
// between JSP lines and Java lines
|
||||
if (errVisitor.getJspSourceNode() instanceof Node.Scriptlet) {
|
||||
javacError = new JavacErrorDetail(
|
||||
fname,
|
||||
lineNum,
|
||||
errNode.getStart().getFile(),
|
||||
errNode.getStart().getLineNumber() + lineNum -
|
||||
errVisitor.getJspSourceNode().getBeginJavaLine(),
|
||||
errMsgBuf,
|
||||
ctxt);
|
||||
} else {
|
||||
javacError = new JavacErrorDetail(
|
||||
fname,
|
||||
lineNum,
|
||||
errNode.getStart().getFile(),
|
||||
errNode.getStart().getLineNumber(),
|
||||
errMsgBuf,
|
||||
ctxt);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* javac error line number cannot be mapped to JSP page
|
||||
* line number. For example, this is the case if a
|
||||
* scriptlet is missing a closing brace, which causes
|
||||
* havoc with the try-catch-finally block that the code
|
||||
* generator places around all generated code: As a result
|
||||
* of this, the javac error line numbers will be outside
|
||||
* the range of begin and end java line numbers that were
|
||||
* generated for the scriptlet, and therefore cannot be
|
||||
* mapped to the start line number of the scriptlet in the
|
||||
* JSP page.
|
||||
* Include just the javac error info in the error detail.
|
||||
*/
|
||||
javacError = new JavacErrorDetail(
|
||||
fname,
|
||||
lineNum,
|
||||
errMsgBuf);
|
||||
}
|
||||
return javacError;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Visitor responsible for mapping a line number in the generated servlet
|
||||
* source code to the corresponding JSP node.
|
||||
*/
|
||||
static class ErrorVisitor extends Node.Visitor {
|
||||
|
||||
// Java source line number to be mapped
|
||||
private int lineNum;
|
||||
|
||||
/*
|
||||
* JSP node whose Java source code range in the generated servlet
|
||||
* contains the Java source line number to be mapped
|
||||
*/
|
||||
Node found;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param lineNum Source line number in the generated servlet code
|
||||
*/
|
||||
public ErrorVisitor(int lineNum) {
|
||||
this.lineNum = lineNum;
|
||||
}
|
||||
|
||||
public void doVisit(Node n) throws JasperException {
|
||||
if ((lineNum >= n.getBeginJavaLine())
|
||||
&& (lineNum < n.getEndJavaLine())) {
|
||||
found = n;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the JSP node to which the source line number in the generated
|
||||
* servlet code was mapped.
|
||||
*
|
||||
* @return JSP node to which the source line number in the generated
|
||||
* servlet code was mapped
|
||||
*/
|
||||
public Node getJspSourceNode() {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
-79
@@ -1,79 +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.struts2.jasper.compiler;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Interface for handling JSP parse and javac compilation errors.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* An implementation of this interface may be registered with the
|
||||
* ErrorDispatcher by setting the XXX initialization parameter in the JSP
|
||||
* page compiler and execution servlet in Catalina's web.xml file to the
|
||||
* implementation's fully qualified class name.
|
||||
* </p>
|
||||
*
|
||||
* @author Jan Luehe
|
||||
* @author Kin-man Chung
|
||||
*/
|
||||
public interface ErrorHandler {
|
||||
|
||||
/**
|
||||
* Processes the given JSP parse error.
|
||||
*
|
||||
* @param fname Name of the JSP file in which the parse error occurred
|
||||
* @param line Parse error line number
|
||||
* @param column Parse error column number
|
||||
* @param msg Parse error message
|
||||
* @param exception Parse exception
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(String fname, int line, int column, String msg, Exception exception) throws JasperException;
|
||||
|
||||
/**
|
||||
* Processes the given JSP parse error.
|
||||
*
|
||||
* @param msg Parse error message
|
||||
* @param exception Parse exception
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void jspError(String msg, Exception exception) throws JasperException;
|
||||
|
||||
/**
|
||||
* Processes the given javac compilation errors.
|
||||
*
|
||||
* @param details Array of JavacErrorDetail instances corresponding to the
|
||||
* compilation errors
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void javacError(JavacErrorDetail[] details)
|
||||
throws JasperException;
|
||||
|
||||
/**
|
||||
* Processes the given javac error report and exception.
|
||||
*
|
||||
* @param errorReport Compilation error report
|
||||
* @param exception Compilation exception
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public void javacError(String errorReport, Exception exception) throws JasperException;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
-219
@@ -1,219 +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.struts2.jasper.compiler;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import jakarta.servlet.jsp.tagext.FunctionInfo;
|
||||
import jakarta.servlet.jsp.tagext.TagFileInfo;
|
||||
import jakarta.servlet.jsp.tagext.TagInfo;
|
||||
import jakarta.servlet.jsp.tagext.TagLibraryInfo;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
import org.apache.struts2.jasper.JspCompilationContext;
|
||||
import org.apache.struts2.jasper.xmlparser.ParserUtils;
|
||||
import org.apache.struts2.jasper.xmlparser.TreeNode;
|
||||
|
||||
/**
|
||||
* Class responsible for generating an implicit tag library containing tag
|
||||
* handlers corresponding to the tag files in "/WEB-INF/tags/" or a
|
||||
* subdirectory of it.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
*/
|
||||
class ImplicitTagLibraryInfo extends TagLibraryInfo {
|
||||
|
||||
private static final String WEB_INF_TAGS = "/WEB-INF/tags";
|
||||
private static final String TAG_FILE_SUFFIX = ".tag";
|
||||
private static final String TAGX_FILE_SUFFIX = ".tagx";
|
||||
private static final String TAGS_SHORTNAME = "tags";
|
||||
private static final String TLIB_VERSION = "1.0";
|
||||
private static final String JSP_VERSION = "2.0";
|
||||
private static final String IMPLICIT_TLD = "implicit.tld";
|
||||
|
||||
// Maps tag names to tag file paths
|
||||
private Hashtable tagFileMap;
|
||||
|
||||
private ParserController pc;
|
||||
private PageInfo pi;
|
||||
private Vector vec;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public ImplicitTagLibraryInfo(JspCompilationContext ctxt,
|
||||
ParserController pc,
|
||||
PageInfo pi,
|
||||
String prefix,
|
||||
String tagdir,
|
||||
ErrorDispatcher err) throws JasperException {
|
||||
super(prefix, null);
|
||||
this.pc = pc;
|
||||
this.pi = pi;
|
||||
this.tagFileMap = new Hashtable();
|
||||
this.vec = new Vector();
|
||||
|
||||
// Implicit tag libraries have no functions:
|
||||
this.functions = new FunctionInfo[0];
|
||||
|
||||
tlibversion = TLIB_VERSION;
|
||||
jspversion = JSP_VERSION;
|
||||
|
||||
if (!tagdir.startsWith(WEB_INF_TAGS)) {
|
||||
err.jspError("jsp.error.invalid.tagdir", tagdir);
|
||||
}
|
||||
|
||||
// Determine the value of the <short-name> subelement of the
|
||||
// "imaginary" <taglib> element
|
||||
if (tagdir.equals(WEB_INF_TAGS)
|
||||
|| tagdir.equals( WEB_INF_TAGS + "/")) {
|
||||
shortname = TAGS_SHORTNAME;
|
||||
} else {
|
||||
shortname = tagdir.substring(WEB_INF_TAGS.length());
|
||||
shortname = shortname.replace('/', '-');
|
||||
}
|
||||
|
||||
// Populate mapping of tag names to tag file paths
|
||||
Set dirList = ctxt.getResourcePaths(tagdir);
|
||||
if (dirList != null) {
|
||||
Iterator it = dirList.iterator();
|
||||
while (it.hasNext()) {
|
||||
String path = (String) it.next();
|
||||
if (path.endsWith(TAG_FILE_SUFFIX)
|
||||
|| path.endsWith(TAGX_FILE_SUFFIX)) {
|
||||
/*
|
||||
* Use the filename of the tag file, without the .tag or
|
||||
* .tagx extension, respectively, as the <name> subelement
|
||||
* of the "imaginary" <tag-file> element
|
||||
*/
|
||||
String suffix = path.endsWith(TAG_FILE_SUFFIX) ?
|
||||
TAG_FILE_SUFFIX : TAGX_FILE_SUFFIX;
|
||||
String tagName = path.substring(path.lastIndexOf("/") + 1);
|
||||
tagName = tagName.substring(0,
|
||||
tagName.lastIndexOf(suffix));
|
||||
tagFileMap.put(tagName, path);
|
||||
} else if (path.endsWith(IMPLICIT_TLD)) {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = ctxt.getResourceAsStream(path);
|
||||
if (in != null) {
|
||||
|
||||
// Add implicit TLD to dependency list
|
||||
if (pi != null) {
|
||||
pi.addDependant(path);
|
||||
}
|
||||
|
||||
ParserUtils pu = new ParserUtils();
|
||||
TreeNode tld = pu.parseXMLDocument(uri, in);
|
||||
|
||||
if (tld.findAttribute("version") != null) {
|
||||
this.jspversion = tld.findAttribute("version");
|
||||
}
|
||||
|
||||
// Process each child element of our <taglib> element
|
||||
Iterator list = tld.findChildren();
|
||||
|
||||
while (list.hasNext()) {
|
||||
TreeNode element = (TreeNode) list.next();
|
||||
String tname = element.getName();
|
||||
|
||||
if ("tlibversion".equals(tname) // JSP 1.1
|
||||
|| "tlib-version".equals(tname)) { // JSP 1.2
|
||||
this.tlibversion = element.getBody();
|
||||
} else if ("jspversion".equals(tname)
|
||||
|| "jsp-version".equals(tname)) {
|
||||
this.jspversion = element.getBody();
|
||||
} else if ("shortname".equals(tname) || "short-name".equals(tname)) {
|
||||
// Ignore
|
||||
} else {
|
||||
// All other elements are invalid
|
||||
err.jspError("jsp.error.invalid.implicit", path);
|
||||
}
|
||||
}
|
||||
try {
|
||||
double version = Double.parseDouble(this.jspversion);
|
||||
if (version < 2.0) {
|
||||
err.jspError("jsp.error.invalid.implicit.version", path);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
err.jspError("jsp.error.invalid.implicit.version", path);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the given tag name maps to a tag file path,
|
||||
* and if so, parses the corresponding tag file.
|
||||
*
|
||||
* @return The TagFileInfo corresponding to the given tag name, or null if
|
||||
* the given tag name is not implemented as a tag file
|
||||
*/
|
||||
public TagFileInfo getTagFile(String shortName) {
|
||||
|
||||
TagFileInfo tagFile = super.getTagFile(shortName);
|
||||
if (tagFile == null) {
|
||||
String path = (String) tagFileMap.get(shortName);
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TagInfo tagInfo = null;
|
||||
try {
|
||||
tagInfo = TagFileProcessor.parseTagFileDirectives(pc,
|
||||
shortName,
|
||||
path,
|
||||
pc.getJspCompilationContext().getTagFileJarUrl(path),
|
||||
this);
|
||||
} catch (JasperException je) {
|
||||
throw new RuntimeException(je.toString(), je);
|
||||
}
|
||||
|
||||
tagFile = new TagFileInfo(shortName, path, tagInfo);
|
||||
vec.addElement(tagFile);
|
||||
|
||||
this.tagFiles = new TagFileInfo[vec.size()];
|
||||
vec.copyInto(this.tagFiles);
|
||||
}
|
||||
|
||||
return tagFile;
|
||||
}
|
||||
|
||||
public TagLibraryInfo[] getTagLibraryInfos() {
|
||||
Collection coll = pi.getTaglibs();
|
||||
return (TagLibraryInfo[]) coll.toArray(new TagLibraryInfo[0]);
|
||||
}
|
||||
|
||||
}
|
||||
-59
@@ -1,59 +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.struts2.jasper.compiler;
|
||||
|
||||
import jakarta.servlet.jsp.tagext.*;
|
||||
|
||||
/**
|
||||
* TagInfo extension used by tag handlers that are implemented via tag files.
|
||||
* This class provides access to the name of the Map used to store the
|
||||
* dynamic attribute names and values passed to the custom action invocation.
|
||||
* This information is used by the code generator.
|
||||
*/
|
||||
class JasperTagInfo extends TagInfo {
|
||||
|
||||
private String dynamicAttrsMapName;
|
||||
|
||||
public JasperTagInfo(String tagName,
|
||||
String tagClassName,
|
||||
String bodyContent,
|
||||
String infoString,
|
||||
TagLibraryInfo taglib,
|
||||
TagExtraInfo tagExtraInfo,
|
||||
TagAttributeInfo[] attributeInfo,
|
||||
String displayName,
|
||||
String smallIcon,
|
||||
String largeIcon,
|
||||
TagVariableInfo[] tvi,
|
||||
String mapName) {
|
||||
|
||||
super(tagName, tagClassName, bodyContent, infoString, taglib,
|
||||
tagExtraInfo, attributeInfo, displayName, smallIcon, largeIcon,
|
||||
tvi);
|
||||
this.dynamicAttrsMapName = mapName;
|
||||
}
|
||||
|
||||
public String getDynamicAttributesMapName() {
|
||||
return dynamicAttrsMapName;
|
||||
}
|
||||
|
||||
public boolean hasDynamicAttributes() {
|
||||
return dynamicAttrsMapName != null;
|
||||
}
|
||||
}
|
||||
-233
@@ -1,233 +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.struts2.jasper.compiler;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.struts2.jasper.JspCompilationContext;
|
||||
|
||||
/**
|
||||
* Class providing details about a javac compilation error.
|
||||
*
|
||||
* @author Jan Luehe
|
||||
* @author Kin-man Chung
|
||||
*/
|
||||
public class JavacErrorDetail {
|
||||
|
||||
private String javaFileName;
|
||||
private int javaLineNum;
|
||||
private String jspFileName;
|
||||
private int jspBeginLineNum;
|
||||
private StringBuffer errMsg;
|
||||
private String jspExtract = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param javaFileName The name of the Java file in which the
|
||||
* compilation error occurred
|
||||
* @param javaLineNum The compilation error line number
|
||||
* @param errMsg The compilation error message
|
||||
*/
|
||||
public JavacErrorDetail(String javaFileName,
|
||||
int javaLineNum,
|
||||
StringBuffer errMsg) {
|
||||
|
||||
this.javaFileName = javaFileName;
|
||||
this.javaLineNum = javaLineNum;
|
||||
this.errMsg = errMsg;
|
||||
this.jspBeginLineNum = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param javaFileName The name of the Java file in which the
|
||||
* compilation error occurred
|
||||
* @param javaLineNum The compilation error line number
|
||||
* @param jspFileName The name of the JSP file from which the Java source
|
||||
* file was generated
|
||||
* @param jspBeginLineNum The start line number of the JSP element
|
||||
* responsible for the compilation error
|
||||
* @param errMsg The compilation error message
|
||||
*/
|
||||
public JavacErrorDetail(String javaFileName,
|
||||
int javaLineNum,
|
||||
String jspFileName,
|
||||
int jspBeginLineNum,
|
||||
StringBuffer errMsg) {
|
||||
|
||||
this(javaFileName, javaLineNum, jspFileName, jspBeginLineNum, errMsg,
|
||||
null);
|
||||
}
|
||||
|
||||
public JavacErrorDetail(String javaFileName,
|
||||
int javaLineNum,
|
||||
String jspFileName,
|
||||
int jspBeginLineNum,
|
||||
StringBuffer errMsg,
|
||||
JspCompilationContext ctxt) {
|
||||
|
||||
this(javaFileName, javaLineNum, errMsg);
|
||||
this.jspFileName = jspFileName;
|
||||
this.jspBeginLineNum = jspBeginLineNum;
|
||||
|
||||
if (jspBeginLineNum > 0 && ctxt != null) {
|
||||
InputStream is = null;
|
||||
FileInputStream fis = null;
|
||||
|
||||
try {
|
||||
// Read both files in, so we can inspect them
|
||||
is = ctxt.getResourceAsStream(jspFileName);
|
||||
String[] jspLines = readFile(is);
|
||||
|
||||
fis = new FileInputStream(ctxt.getServletJavaFileName());
|
||||
String[] javaLines = readFile(fis);
|
||||
|
||||
// If the line contains the opening of a multi-line scriptlet
|
||||
// block, then the JSP line number we got back is probably
|
||||
// faulty. Scan forward to match the java line...
|
||||
if (jspLines[jspBeginLineNum-1].lastIndexOf("<%") >
|
||||
jspLines[jspBeginLineNum-1].lastIndexOf("%>")) {
|
||||
String javaLine = javaLines[javaLineNum-1].trim();
|
||||
|
||||
for (int i=jspBeginLineNum-1; i<jspLines.length; i++) {
|
||||
if (jspLines[i].indexOf(javaLine) != -1) {
|
||||
// Update jsp line number
|
||||
this.jspBeginLineNum = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy out a fragment of JSP to display to the user
|
||||
StringBuffer fragment = new StringBuffer(1024);
|
||||
int startIndex = Math.max(0, this.jspBeginLineNum-1-3);
|
||||
int endIndex = Math.min(
|
||||
jspLines.length-1, this.jspBeginLineNum-1+3);
|
||||
|
||||
for (int i=startIndex;i<=endIndex; ++i) {
|
||||
fragment.append(i+1);
|
||||
fragment.append(": ");
|
||||
fragment.append(jspLines[i]);
|
||||
fragment.append("\n");
|
||||
}
|
||||
jspExtract = fragment.toString();
|
||||
|
||||
} catch (IOException ioe) {
|
||||
// Can't read files - ignore
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException ioe) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException ioe) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the Java source file in which the compilation error
|
||||
* occurred.
|
||||
*
|
||||
* @return Java source file name
|
||||
*/
|
||||
public String getJavaFileName() {
|
||||
return this.javaFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the compilation error line number.
|
||||
*
|
||||
* @return Compilation error line number
|
||||
*/
|
||||
public int getJavaLineNumber() {
|
||||
return this.javaLineNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the JSP file from which the Java source file was
|
||||
* generated.
|
||||
*
|
||||
* @return JSP file from which the Java source file was generated.
|
||||
*/
|
||||
public String getJspFileName() {
|
||||
return this.jspFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the start line number (in the JSP file) of the JSP element
|
||||
* responsible for the compilation error.
|
||||
*
|
||||
* @return Start line number of the JSP element responsible for the
|
||||
* compilation error
|
||||
*/
|
||||
public int getJspBeginLineNumber() {
|
||||
return this.jspBeginLineNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the compilation error message.
|
||||
*
|
||||
* @return Compilation error message
|
||||
*/
|
||||
public String getErrorMessage() {
|
||||
return this.errMsg.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extract of the JSP that corresponds to this message.
|
||||
*
|
||||
* @return Extract of JSP where error occurred
|
||||
*/
|
||||
public String getJspExtract() {
|
||||
return this.jspExtract;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a text file from an input stream into a String[]. Used to read in
|
||||
* the JSP and generated Java file when generating error messages.
|
||||
*/
|
||||
private String[] readFile(InputStream s) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(s));
|
||||
List lines = new ArrayList();
|
||||
String line;
|
||||
|
||||
while ( (line = reader.readLine()) != null ) {
|
||||
lines.add(line);
|
||||
}
|
||||
|
||||
return (String[]) lines.toArray( new String[lines.size()] );
|
||||
}
|
||||
}
|
||||
@@ -1,536 +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.struts2.jasper.compiler;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Vector;
|
||||
import java.net.URL;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
|
||||
import org.apache.struts2.jasper.JasperException;
|
||||
import org.apache.struts2.jasper.xmlparser.ParserUtils;
|
||||
import org.apache.struts2.jasper.xmlparser.TreeNode;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* Handles the jsp-config element in WEB_INF/web.xml. This is used
|
||||
* for specifying the JSP configuration information on a JSP page
|
||||
*
|
||||
* @author Kin-man Chung
|
||||
* @author Remy Maucherat
|
||||
*/
|
||||
|
||||
public class JspConfig {
|
||||
|
||||
private static final String WEB_XML = "/WEB-INF/web.xml";
|
||||
|
||||
// Logger
|
||||
private Log log = LogFactory.getLog(JspConfig.class);
|
||||
|
||||
private Vector jspProperties = null;
|
||||
private ServletContext ctxt;
|
||||
private boolean initialized = false;
|
||||
|
||||
private String defaultIsXml = null; // unspecified
|
||||
private String defaultIsELIgnored = null; // unspecified
|
||||
private String defaultIsScriptingInvalid = null;
|
||||
private String defaultDeferedSyntaxAllowedAsLiteral = null;
|
||||
private String defaultTrimDirectiveWhitespaces = null;
|
||||
private JspProperty defaultJspProperty;
|
||||
|
||||
public JspConfig(ServletContext ctxt) {
|
||||
this.ctxt = ctxt;
|
||||
}
|
||||
|
||||
private double getVersion(TreeNode webApp) {
|
||||
String v = webApp.findAttribute("version");
|
||||
if (v != null) {
|
||||
try {
|
||||
return Double.parseDouble(v);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
return 2.3;
|
||||
}
|
||||
|
||||
private void processWebDotXml(ServletContext ctxt) throws JasperException {
|
||||
|
||||
InputStream is = null;
|
||||
|
||||
try {
|
||||
URL uri = ctxt.getResource(WEB_XML);
|
||||
if (uri == null) {
|
||||
// no web.xml
|
||||
return;
|
||||
}
|
||||
|
||||
is = uri.openStream();
|
||||
InputSource ip = new InputSource(is);
|
||||
ip.setSystemId(uri.toExternalForm());
|
||||
|
||||
ParserUtils pu = new ParserUtils();
|
||||
TreeNode webApp = pu.parseXMLDocument(WEB_XML, ip);
|
||||
|
||||
if (webApp == null
|
||||
|| getVersion(webApp) < 2.4) {
|
||||
defaultIsELIgnored = "true";
|
||||
return;
|
||||
}
|
||||
TreeNode jspConfig = webApp.findChild("jsp-config");
|
||||
if (jspConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
jspProperties = new Vector();
|
||||
Iterator jspPropertyList = jspConfig.findChildren("jsp-property-group");
|
||||
while (jspPropertyList.hasNext()) {
|
||||
|
||||
TreeNode element = (TreeNode) jspPropertyList.next();
|
||||
Iterator list = element.findChildren();
|
||||
|
||||
Vector urlPatterns = new Vector();
|
||||
String pageEncoding = null;
|
||||
String scriptingInvalid = null;
|
||||
String elIgnored = null;
|
||||
String isXml = null;
|
||||
Vector includePrelude = new Vector();
|
||||
Vector includeCoda = new Vector();
|
||||
String deferredSyntaxAllowedAsLiteral = null;
|
||||
String trimDirectiveWhitespaces = null;
|
||||
|
||||
while (list.hasNext()) {
|
||||
|
||||
element = (TreeNode) list.next();
|
||||
String tname = element.getName();
|
||||
|
||||
if ("url-pattern".equals(tname))
|
||||
urlPatterns.addElement( element.getBody() );
|
||||
else if ("page-encoding".equals(tname))
|
||||
pageEncoding = element.getBody();
|
||||
else if ("is-xml".equals(tname))
|
||||
isXml = element.getBody();
|
||||
else if ("el-ignored".equals(tname))
|
||||
elIgnored = element.getBody();
|
||||
else if ("scripting-invalid".equals(tname))
|
||||
scriptingInvalid = element.getBody();
|
||||
else if ("include-prelude".equals(tname))
|
||||
includePrelude.addElement(element.getBody());
|
||||
else if ("include-coda".equals(tname))
|
||||
includeCoda.addElement(element.getBody());
|
||||
else if ("deferred-syntax-allowed-as-literal".equals(tname))
|
||||
deferredSyntaxAllowedAsLiteral = element.getBody();
|
||||
else if ("trim-directive-whitespaces".equals(tname))
|
||||
trimDirectiveWhitespaces = element.getBody();
|
||||
}
|
||||
|
||||
if (urlPatterns.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add one JspPropertyGroup for each URL Pattern. This makes
|
||||
// the matching logic easier.
|
||||
for( int p = 0; p < urlPatterns.size(); p++ ) {
|
||||
String urlPattern = (String)urlPatterns.elementAt( p );
|
||||
String path = null;
|
||||
String extension = null;
|
||||
|
||||
if (urlPattern.indexOf('*') < 0) {
|
||||
// Exact match
|
||||
path = urlPattern;
|
||||
} else {
|
||||
int i = urlPattern.lastIndexOf('/');
|
||||
String file;
|
||||
if (i >= 0) {
|
||||
path = urlPattern.substring(0,i+1);
|
||||
file = urlPattern.substring(i+1);
|
||||
} else {
|
||||
file = urlPattern;
|
||||
}
|
||||
|
||||
// pattern must be "*", or of the form "*.jsp"
|
||||
if (file.equals("*")) {
|
||||
extension = "*";
|
||||
} else if (file.startsWith("*.")) {
|
||||
extension = file.substring(file.indexOf('.')+1);
|
||||
}
|
||||
|
||||
// The url patterns are reconstructed as the follwoing:
|
||||
// path != null, extension == null: / or /foo/bar.ext
|
||||
// path == null, extension != null: *.ext
|
||||
// path != null, extension == "*": /foo/*
|
||||
boolean isStar = "*".equals(extension);
|
||||
if ((path == null && (extension == null || isStar))
|
||||
|| (path != null && !isStar)) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn(Localizer.getMessage(
|
||||
"jsp.warning.bad.urlpattern.propertygroup",
|
||||
urlPattern));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
JspProperty property = new JspProperty(isXml,
|
||||
elIgnored,
|
||||
scriptingInvalid,
|
||||
pageEncoding,
|
||||
includePrelude,
|
||||
includeCoda,
|
||||
deferredSyntaxAllowedAsLiteral,
|
||||
trimDirectiveWhitespaces);
|
||||
JspPropertyGroup propertyGroup =
|
||||
new JspPropertyGroup(path, extension, property);
|
||||
|
||||
jspProperties.addElement(propertyGroup);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new JasperException(ex);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void init() throws JasperException {
|
||||
|
||||
if (!initialized) {
|
||||
processWebDotXml(ctxt);
|
||||
defaultJspProperty = new JspProperty(defaultIsXml,
|
||||
defaultIsELIgnored,
|
||||
defaultIsScriptingInvalid,
|
||||
null, null, null, defaultDeferedSyntaxAllowedAsLiteral,
|
||||
defaultTrimDirectiveWhitespaces);
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the property group that has more restrictive url-pattern.
|
||||
* In case of tie, select the first.
|
||||
*/
|
||||
private JspPropertyGroup selectProperty(JspPropertyGroup prev,
|
||||
JspPropertyGroup curr) {
|
||||
if (prev == null) {
|
||||
return curr;
|
||||
}
|
||||
if (prev.getExtension() == null) {
|
||||
// exact match
|
||||
return prev;
|
||||
}
|
||||
if (curr.getExtension() == null) {
|
||||
// exact match
|
||||
return curr;
|
||||
}
|
||||
String prevPath = prev.getPath();
|
||||
String currPath = curr.getPath();
|
||||
if (prevPath == null && currPath == null) {
|
||||
// Both specifies a *.ext, keep the first one
|
||||
return prev;
|
||||
}
|
||||
if (prevPath == null && currPath != null) {
|
||||
return curr;
|
||||
}
|
||||
if (prevPath != null && currPath == null) {
|
||||
return prev;
|
||||
}
|
||||
if (prevPath.length() >= currPath.length()) {
|
||||
return prev;
|
||||
}
|
||||
return curr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find a property that best matches the supplied resource.
|
||||
* @param uri the resource supplied.
|
||||
* @return a JspProperty indicating the best match, or some default.
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public JspProperty findJspProperty(String uri) throws JasperException {
|
||||
|
||||
init();
|
||||
|
||||
// JSP Configuration settings do not apply to tag files
|
||||
if (jspProperties == null || uri.endsWith(".tag")
|
||||
|| uri.endsWith(".tagx")) {
|
||||
return defaultJspProperty;
|
||||
}
|
||||
|
||||
String uriPath = null;
|
||||
int index = uri.lastIndexOf('/');
|
||||
if (index >=0 ) {
|
||||
uriPath = uri.substring(0, index+1);
|
||||
}
|
||||
String uriExtension = null;
|
||||
index = uri.lastIndexOf('.');
|
||||
if (index >=0) {
|
||||
uriExtension = uri.substring(index+1);
|
||||
}
|
||||
|
||||
Vector includePreludes = new Vector();
|
||||
Vector includeCodas = new Vector();
|
||||
|
||||
JspPropertyGroup isXmlMatch = null;
|
||||
JspPropertyGroup elIgnoredMatch = null;
|
||||
JspPropertyGroup scriptingInvalidMatch = null;
|
||||
JspPropertyGroup pageEncodingMatch = null;
|
||||
JspPropertyGroup deferedSyntaxAllowedAsLiteralMatch = null;
|
||||
JspPropertyGroup trimDirectiveWhitespacesMatch = null;
|
||||
|
||||
Iterator iter = jspProperties.iterator();
|
||||
while (iter.hasNext()) {
|
||||
|
||||
JspPropertyGroup jpg = (JspPropertyGroup) iter.next();
|
||||
JspProperty jp = jpg.getJspProperty();
|
||||
|
||||
// (arrays will be the same length)
|
||||
String extension = jpg.getExtension();
|
||||
String path = jpg.getPath();
|
||||
|
||||
if (extension == null) {
|
||||
// exact match pattern: /a/foo.jsp
|
||||
if (!uri.equals(path)) {
|
||||
// not matched;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Matching patterns *.ext or /p/*
|
||||
if (path != null && uriPath != null &&
|
||||
! uriPath.startsWith(path)) {
|
||||
// not matched
|
||||
continue;
|
||||
}
|
||||
if (!extension.equals("*") &&
|
||||
!extension.equals(uriExtension)) {
|
||||
// not matched
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// We have a match
|
||||
// Add include-preludes and include-codas
|
||||
if (jp.getIncludePrelude() != null) {
|
||||
includePreludes.addAll(jp.getIncludePrelude());
|
||||
}
|
||||
if (jp.getIncludeCoda() != null) {
|
||||
includeCodas.addAll(jp.getIncludeCoda());
|
||||
}
|
||||
|
||||
// If there is a previous match for the same property, remember
|
||||
// the one that is more restrictive.
|
||||
if (jp.isXml() != null) {
|
||||
isXmlMatch = selectProperty(isXmlMatch, jpg);
|
||||
}
|
||||
if (jp.isELIgnored() != null) {
|
||||
elIgnoredMatch = selectProperty(elIgnoredMatch, jpg);
|
||||
}
|
||||
if (jp.isScriptingInvalid() != null) {
|
||||
scriptingInvalidMatch =
|
||||
selectProperty(scriptingInvalidMatch, jpg);
|
||||
}
|
||||
if (jp.getPageEncoding() != null) {
|
||||
pageEncodingMatch = selectProperty(pageEncodingMatch, jpg);
|
||||
}
|
||||
if (jp.isDeferedSyntaxAllowedAsLiteral() != null) {
|
||||
deferedSyntaxAllowedAsLiteralMatch =
|
||||
selectProperty(deferedSyntaxAllowedAsLiteralMatch, jpg);
|
||||
}
|
||||
if (jp.isTrimDirectiveWhitespaces() != null) {
|
||||
trimDirectiveWhitespacesMatch =
|
||||
selectProperty(trimDirectiveWhitespacesMatch, jpg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String isXml = defaultIsXml;
|
||||
String isELIgnored = defaultIsELIgnored;
|
||||
String isScriptingInvalid = defaultIsScriptingInvalid;
|
||||
String pageEncoding = null;
|
||||
String isDeferedSyntaxAllowedAsLiteral = defaultDeferedSyntaxAllowedAsLiteral;
|
||||
String isTrimDirectiveWhitespaces = defaultTrimDirectiveWhitespaces;
|
||||
|
||||
if (isXmlMatch != null) {
|
||||
isXml = isXmlMatch.getJspProperty().isXml();
|
||||
}
|
||||
if (elIgnoredMatch != null) {
|
||||
isELIgnored = elIgnoredMatch.getJspProperty().isELIgnored();
|
||||
}
|
||||
if (scriptingInvalidMatch != null) {
|
||||
isScriptingInvalid =
|
||||
scriptingInvalidMatch.getJspProperty().isScriptingInvalid();
|
||||
}
|
||||
if (pageEncodingMatch != null) {
|
||||
pageEncoding = pageEncodingMatch.getJspProperty().getPageEncoding();
|
||||
}
|
||||
if (deferedSyntaxAllowedAsLiteralMatch != null) {
|
||||
isDeferedSyntaxAllowedAsLiteral =
|
||||
deferedSyntaxAllowedAsLiteralMatch.getJspProperty().isDeferedSyntaxAllowedAsLiteral();
|
||||
}
|
||||
if (trimDirectiveWhitespacesMatch != null) {
|
||||
isTrimDirectiveWhitespaces =
|
||||
trimDirectiveWhitespacesMatch.getJspProperty().isTrimDirectiveWhitespaces();
|
||||
}
|
||||
|
||||
return new JspProperty(isXml, isELIgnored, isScriptingInvalid,
|
||||
pageEncoding, includePreludes, includeCodas,
|
||||
isDeferedSyntaxAllowedAsLiteral, isTrimDirectiveWhitespaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* To find out if an uri matches an url pattern in jsp config. If so,
|
||||
* then the uri is a JSP page. This is used primarily for jspc.
|
||||
*
|
||||
* @param uri the uri
|
||||
* @return true if uri is a JSP page
|
||||
* @throws JasperException in case of Jasper errors
|
||||
*/
|
||||
public boolean isJspPage(String uri) throws JasperException {
|
||||
|
||||
init();
|
||||
if (jspProperties == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String uriPath = null;
|
||||
int index = uri.lastIndexOf('/');
|
||||
if (index >=0 ) {
|
||||
uriPath = uri.substring(0, index+1);
|
||||
}
|
||||
String uriExtension = null;
|
||||
index = uri.lastIndexOf('.');
|
||||
if (index >=0) {
|
||||
uriExtension = uri.substring(index+1);
|
||||
}
|
||||
|
||||
for (Object jspProperty : jspProperties) {
|
||||
|
||||
JspPropertyGroup jpg = (JspPropertyGroup) jspProperty;
|
||||
JspProperty jp = jpg.getJspProperty();
|
||||
|
||||
String extension = jpg.getExtension();
|
||||
String path = jpg.getPath();
|
||||
|
||||
if (extension == null) {
|
||||
if (uri.equals(path)) {
|
||||
// There is an exact match
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ((path == null || path.equals(uriPath)) &&
|
||||
(extension.equals("*") || extension.equals(uriExtension))) {
|
||||
// Matches *, *.ext, /p/*, or /p/*.ext
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static class JspPropertyGroup {
|
||||
private String path;
|
||||
private String extension;
|
||||
private JspProperty jspProperty;
|
||||
|
||||
JspPropertyGroup(String path, String extension,
|
||||
JspProperty jspProperty) {
|
||||
this.path = path;
|
||||
this.extension = extension;
|
||||
this.jspProperty = jspProperty;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getExtension() {
|
||||
return extension;
|
||||
}
|
||||
|
||||
public JspProperty getJspProperty() {
|
||||
return jspProperty;
|
||||
}
|
||||
}
|
||||
|
||||
static public class JspProperty {
|
||||
|
||||
private String isXml;
|
||||
private String elIgnored;
|
||||
private String scriptingInvalid;
|
||||
private String pageEncoding;
|
||||
private Vector includePrelude;
|
||||
private Vector includeCoda;
|
||||
private String deferedSyntaxAllowedAsLiteral;
|
||||
private String trimDirectiveWhitespaces;
|
||||
|
||||
public JspProperty(String isXml, String elIgnored,
|
||||
String scriptingInvalid, String pageEncoding,
|
||||
Vector includePrelude, Vector includeCoda,
|
||||
String deferedSyntaxAllowedAsLiteral,
|
||||
String trimDirectiveWhitespaces) {
|
||||
|
||||
this.isXml = isXml;
|
||||
this.elIgnored = elIgnored;
|
||||
this.scriptingInvalid = scriptingInvalid;
|
||||
this.pageEncoding = pageEncoding;
|
||||
this.includePrelude = includePrelude;
|
||||
this.includeCoda = includeCoda;
|
||||
this.deferedSyntaxAllowedAsLiteral = deferedSyntaxAllowedAsLiteral;
|
||||
this.trimDirectiveWhitespaces = trimDirectiveWhitespaces;
|
||||
}
|
||||
|
||||
public String isXml() {
|
||||
return isXml;
|
||||
}
|
||||
|
||||
public String isELIgnored() {
|
||||
return elIgnored;
|
||||
}
|
||||
|
||||
public String isScriptingInvalid() {
|
||||
return scriptingInvalid;
|
||||
}
|
||||
|
||||
public String getPageEncoding() {
|
||||
return pageEncoding;
|
||||
}
|
||||
|
||||
public Vector getIncludePrelude() {
|
||||
return includePrelude;
|
||||
}
|
||||
|
||||
public Vector getIncludeCoda() {
|
||||
return includeCoda;
|
||||
}
|
||||
|
||||
public String isDeferedSyntaxAllowedAsLiteral() {
|
||||
return deferedSyntaxAllowedAsLiteral;
|
||||
}
|
||||
|
||||
public String isTrimDirectiveWhitespaces() {
|
||||
return trimDirectiveWhitespaces;
|
||||
}
|
||||
}
|
||||
}
|
||||
-1455
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user