You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2009/09/28 03:55:35 UTC

svn commit: r819444 [20/27] - in /struts/struts2/trunk/plugins/embeddedjsp: ./ src/main/java/org/apache/struts2/el/ src/main/java/org/apache/struts2/el/lang/ src/main/java/org/apache/struts2/el/parser/ src/main/java/org/apache/struts2/el/util/ src/main...

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.jasper.el;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+
+/**
+ * Implementation of ELContext
+ * 
+ * @author Jacob Hookom
+ */
+public final class ELContextImpl extends ELContext {
+
+    private final static FunctionMapper NullFunctionMapper = new FunctionMapper() {
+        public Method resolveFunction(String prefix, String localName) {
+            return null;
+        }
+    };
+
+    private final static class VariableMapperImpl extends VariableMapper {
+
+        private Map<String, ValueExpression> vars;
+
+        public ValueExpression resolveVariable(String variable) {
+            if (vars == null) {
+                return null;
+            }
+            return vars.get(variable);
+        }
+
+        public ValueExpression setVariable(String variable,
+                ValueExpression expression) {
+            if (vars == null)
+                vars = new HashMap<String, ValueExpression>();
+            return vars.put(variable, expression);
+        }
+
+    }
+
+    private final ELResolver resolver;
+
+    private FunctionMapper functionMapper = NullFunctionMapper; // immutable
+
+    private VariableMapper variableMapper;
+
+    public ELContextImpl() {
+        this(ELResolverImpl.DefaultResolver);
+    }
+
+    public ELContextImpl(ELResolver resolver) {
+        this.resolver = resolver;
+    }
+
+    public ELResolver getELResolver() {
+        return this.resolver;
+    }
+
+    public FunctionMapper getFunctionMapper() {
+        return this.functionMapper;
+    }
+
+    public VariableMapper getVariableMapper() {
+        if (this.variableMapper == null) {
+            this.variableMapper = new VariableMapperImpl();
+        }
+        return this.variableMapper;
+    }
+
+    public void setFunctionMapper(FunctionMapper functionMapper) {
+        this.functionMapper = functionMapper;
+    }
+
+    public void setVariableMapper(VariableMapper variableMapper) {
+        this.variableMapper = variableMapper;
+    }
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextWrapper.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextWrapper.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextWrapper.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELContextWrapper.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,78 @@
+/*
+ * 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.el;
+
+import java.util.Locale;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.VariableMapper;
+
+/**
+ * Simple ELContextWrapper for runtime evaluation of EL w/ dynamic FunctionMappers
+ * 
+ * @author jhook
+ */
+public final class ELContextWrapper extends ELContext {
+
+    private final ELContext target;
+    private final FunctionMapper fnMapper;
+    
+    public ELContextWrapper(ELContext target, FunctionMapper fnMapper) {
+        this.target = target;
+        this.fnMapper = fnMapper;
+    }
+
+    public ELResolver getELResolver() {
+        return this.target.getELResolver();
+    }
+
+    public FunctionMapper getFunctionMapper() {
+        if (this.fnMapper != null) return this.fnMapper;
+        return this.target.getFunctionMapper();
+    }
+
+    public VariableMapper getVariableMapper() {
+        return this.target.getVariableMapper();
+    }
+
+    public Object getContext(Class key) {
+        return this.target.getContext(key);
+    }
+
+    public Locale getLocale() {
+        return this.target.getLocale();
+    }
+
+    public boolean isPropertyResolved() {
+        return this.target.isPropertyResolved();
+    }
+
+    public void putContext(Class key, Object contextObject) throws NullPointerException {
+        this.target.putContext(key, contextObject);
+    }
+
+    public void setLocale(Locale locale) {
+        this.target.setLocale(locale);
+    }
+
+    public void setPropertyResolved(boolean resolved) {
+        this.target.setPropertyResolved(resolved);
+    }
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELResolverImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELResolverImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELResolverImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ELResolverImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,146 @@
+/*
+ * 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.el;
+
+import java.util.Iterator;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.el.ResourceBundleELResolver;
+import javax.servlet.jsp.el.VariableResolver;
+
+public final class ELResolverImpl extends ELResolver {
+	
+	public final static ELResolver DefaultResolver = new CompositeELResolver();
+
+	static {
+		((CompositeELResolver) DefaultResolver).add(new MapELResolver());
+		((CompositeELResolver) DefaultResolver).add(new ResourceBundleELResolver());
+		((CompositeELResolver) DefaultResolver).add(new ListELResolver());
+		((CompositeELResolver) DefaultResolver).add(new ArrayELResolver());
+		((CompositeELResolver) DefaultResolver).add(new BeanELResolver());
+	}
+
+	private final VariableResolver variableResolver;
+
+	public ELResolverImpl(VariableResolver variableResolver) {
+		this.variableResolver = variableResolver;
+	}
+
+	public Object getValue(ELContext context, Object base, Object property)
+			throws NullPointerException, PropertyNotFoundException, ELException {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+
+		if (base == null) {
+			context.setPropertyResolved(true);
+			if (property != null) {
+				try {
+					return this.variableResolver.resolveVariable(property
+							.toString());
+				} catch (javax.servlet.jsp.el.ELException e) {
+					throw new ELException(e.getMessage(), e.getCause());
+				}
+			}
+		}
+
+		if (!context.isPropertyResolved()) {
+			return DefaultResolver.getValue(context, base, property);
+		}
+		return null;
+	}
+
+	public Class<?> getType(ELContext context, Object base, Object property)
+			throws NullPointerException, PropertyNotFoundException, ELException {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+
+		if (base == null) {
+			context.setPropertyResolved(true);
+			if (property != null) {
+				try {
+					Object obj = this.variableResolver.resolveVariable(property
+							.toString());
+					return (obj != null) ? obj.getClass() : null;
+				} catch (javax.servlet.jsp.el.ELException e) {
+					throw new ELException(e.getMessage(), e.getCause());
+				}
+			}
+		}
+
+		if (!context.isPropertyResolved()) {
+			return DefaultResolver.getType(context, base, property);
+		}
+		return null;
+	}
+
+	public void setValue(ELContext context, Object base, Object property,
+			Object value) throws NullPointerException,
+			PropertyNotFoundException, PropertyNotWritableException,
+			ELException {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+
+		if (base == null) {
+			context.setPropertyResolved(true);
+			throw new PropertyNotWritableException(
+					"Legacy VariableResolver wrapped, not writable");
+		}
+
+		if (!context.isPropertyResolved()) {
+			DefaultResolver.setValue(context, base, property, value);
+		}
+	}
+
+	public boolean isReadOnly(ELContext context, Object base, Object property)
+			throws NullPointerException, PropertyNotFoundException, ELException {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+
+		if (base == null) {
+			context.setPropertyResolved(true);
+			return true;
+		}
+
+		return DefaultResolver.isReadOnly(context, base, property);
+	}
+
+	public Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
+		return DefaultResolver.getFeatureDescriptors(context, base);
+	}
+
+	public Class<?> getCommonPropertyType(ELContext context, Object base) {
+		if (base == null) {
+			return String.class;
+		}
+		return DefaultResolver.getCommonPropertyType(context, base);
+	}
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionEvaluatorImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionEvaluatorImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionEvaluatorImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionEvaluatorImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,58 @@
+/*
+ * 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.el;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.el.ValueExpression;
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.ELParseException;
+import javax.servlet.jsp.el.Expression;
+import javax.servlet.jsp.el.ExpressionEvaluator;
+import javax.servlet.jsp.el.FunctionMapper;
+import javax.servlet.jsp.el.VariableResolver;
+
+
+public final class ExpressionEvaluatorImpl extends ExpressionEvaluator {
+
+	private final ExpressionFactory factory;
+	
+	public ExpressionEvaluatorImpl(ExpressionFactory factory) {
+		this.factory = factory;
+	}
+
+	public Expression parseExpression(String expression, Class expectedType,
+			FunctionMapper fMapper) throws ELException {
+		try {
+			ELContextImpl ctx = new ELContextImpl(ELResolverImpl.DefaultResolver);
+            if (fMapper != null) {
+                ctx.setFunctionMapper(new FunctionMapperImpl(fMapper));
+            }
+			ValueExpression ve = this.factory.createValueExpression(ctx, expression, expectedType);
+			return new ExpressionImpl(ve);
+		} catch (javax.el.ELException e) {
+			throw new ELParseException(e.getMessage());
+		}
+	}
+
+	public Object evaluate(String expression, Class expectedType,
+			VariableResolver vResolver, FunctionMapper fMapper)
+			throws ELException {
+		return this.parseExpression(expression, expectedType, fMapper).evaluate(vResolver);
+	}
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/ExpressionImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,38 @@
+/*
+ * 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.el;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.Expression;
+import javax.servlet.jsp.el.VariableResolver;
+
+public final class ExpressionImpl extends Expression {
+
+	private final ValueExpression ve;
+	
+	public ExpressionImpl(ValueExpression ve) {
+		this.ve = ve;
+	}
+
+	public Object evaluate(VariableResolver vResolver) throws ELException {
+		ELContext ctx = new ELContextImpl(new ELResolverImpl(vResolver));
+		return ve.getValue(ctx);
+	}
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/FunctionMapperImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/FunctionMapperImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/FunctionMapperImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/FunctionMapperImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,35 @@
+/*
+ * 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.el;
+
+import java.lang.reflect.Method;
+
+import javax.servlet.jsp.el.FunctionMapper;
+
+public final class FunctionMapperImpl extends javax.el.FunctionMapper {
+	
+	private final FunctionMapper fnMapper;
+
+	public FunctionMapperImpl(FunctionMapper fnMapper) {
+		this.fnMapper = fnMapper;
+	}
+
+	public Method resolveFunction(String prefix, String localName) {
+		return this.fnMapper.resolveFunction(prefix, localName);
+	}
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspELException.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspELException.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspELException.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspELException.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,26 @@
+/*
+ * 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.el;
+
+import javax.el.ELException;
+
+public class JspELException extends ELException {
+
+    public JspELException(String mark, ELException e) {
+        super(mark + " " + e.getMessage(), e.getCause());
+    }
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodExpression.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodExpression.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodExpression.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodExpression.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,108 @@
+/*
+ * 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.el;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.MethodExpression;
+import javax.el.MethodInfo;
+import javax.el.MethodNotFoundException;
+import javax.el.PropertyNotFoundException;
+
+public final class JspMethodExpression extends MethodExpression implements
+        Externalizable {
+
+    private String mark;
+
+    private MethodExpression target;
+
+    public JspMethodExpression() {
+        super();
+    }
+
+    public JspMethodExpression(String mark, MethodExpression target) {
+        this.target = target;
+        this.mark = mark;
+    }
+
+    public MethodInfo getMethodInfo(ELContext context)
+            throws NullPointerException, PropertyNotFoundException,
+            MethodNotFoundException, ELException {
+        try {
+            return this.target.getMethodInfo(context);
+        } catch (MethodNotFoundException e) {
+            if (e instanceof JspMethodNotFoundException) throw e;
+            throw new JspMethodNotFoundException(this.mark, e);
+        } catch (PropertyNotFoundException e) {
+            if (e instanceof JspPropertyNotFoundException) throw e;
+            throw new JspPropertyNotFoundException(this.mark, e);
+        } catch (ELException e) {
+            if (e instanceof JspELException) throw e;
+            throw new JspELException(this.mark, e);
+        }
+    }
+
+    public Object invoke(ELContext context, Object[] params)
+            throws NullPointerException, PropertyNotFoundException,
+            MethodNotFoundException, ELException {
+        try {
+            return this.target.invoke(context, params);
+        } catch (MethodNotFoundException e) {
+            if (e instanceof JspMethodNotFoundException) throw e;
+            throw new JspMethodNotFoundException(this.mark, e);
+        } catch (PropertyNotFoundException e) {
+            if (e instanceof JspPropertyNotFoundException) throw e;
+            throw new JspPropertyNotFoundException(this.mark, e);
+        } catch (ELException e) {
+            if (e instanceof JspELException) throw e;
+            throw new JspELException(this.mark, e);
+        }
+    }
+
+    public boolean equals(Object obj) {
+        return this.target.equals(obj);
+    }
+
+    public int hashCode() {
+        return this.target.hashCode();
+    }
+
+    public String getExpressionString() {
+        return this.target.getExpressionString();
+    }
+
+    public boolean isLiteralText() {
+        return this.target.isLiteralText();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeUTF(this.mark);
+        out.writeObject(this.target);
+    }
+
+    public void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+        this.mark = in.readUTF();
+        this.target = (MethodExpression) in.readObject();
+    }
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodNotFoundException.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodNotFoundException.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodNotFoundException.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspMethodNotFoundException.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,26 @@
+/*
+ * 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.el;
+
+import javax.el.MethodNotFoundException;
+
+public class JspMethodNotFoundException extends MethodNotFoundException {
+
+    public JspMethodNotFoundException(String mark, MethodNotFoundException e) {
+        super(mark + " " + e.getMessage(), e.getCause());
+    }
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotFoundException.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotFoundException.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotFoundException.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotFoundException.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.el;
+
+import javax.el.PropertyNotFoundException;
+
+public final class JspPropertyNotFoundException extends
+        PropertyNotFoundException {
+
+    public JspPropertyNotFoundException(String mark, PropertyNotFoundException e) {
+        super(mark + " " + e.getMessage(), e.getCause());
+    }
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotWritableException.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotWritableException.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotWritableException.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspPropertyNotWritableException.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,27 @@
+/*
+ * 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.el;
+
+import javax.el.PropertyNotWritableException;
+
+public class JspPropertyNotWritableException extends
+        PropertyNotWritableException {
+
+    public JspPropertyNotWritableException(String mark, PropertyNotWritableException e) {
+        super(mark + " " + e.getMessage(), e.getCause());
+    }
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspValueExpression.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspValueExpression.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspValueExpression.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/JspValueExpression.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,137 @@
+/*
+ * 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.el;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.el.ValueExpression;
+
+/**
+ * Wrapper for providing context to ValueExpressions
+ * 
+ * @author Jacob Hookom
+ */
+public final class JspValueExpression extends ValueExpression implements
+        Externalizable {
+
+    private ValueExpression target;
+
+    private String mark;
+
+    public JspValueExpression() {
+        super();
+    }
+
+    public JspValueExpression(String mark, ValueExpression target) {
+        this.target = target;
+        this.mark = mark;
+    }
+
+    public Class<?> getExpectedType() {
+        return this.target.getExpectedType();
+    }
+
+    public Class<?> getType(ELContext context) throws NullPointerException,
+            PropertyNotFoundException, ELException {
+        try {
+            return this.target.getType(context);
+        } catch (PropertyNotFoundException e) {
+            if (e instanceof JspPropertyNotFoundException) throw e;
+            throw new JspPropertyNotFoundException(this.mark, e);
+        } catch (ELException e) {
+            if (e instanceof JspELException) throw e;
+            throw new JspELException(this.mark, e);
+        }
+    }
+
+    public boolean isReadOnly(ELContext context) throws NullPointerException,
+            PropertyNotFoundException, ELException {
+        try {
+            return this.target.isReadOnly(context);
+        } catch (PropertyNotFoundException e) {
+            if (e instanceof JspPropertyNotFoundException) throw e;
+            throw new JspPropertyNotFoundException(this.mark, e);
+        } catch (ELException e) {
+            if (e instanceof JspELException) throw e;
+            throw new JspELException(this.mark, e);
+        }
+    }
+
+    public void setValue(ELContext context, Object value)
+            throws NullPointerException, PropertyNotFoundException,
+            PropertyNotWritableException, ELException {
+        try {
+            this.target.setValue(context, value);
+        } catch (PropertyNotWritableException e) {
+            if (e instanceof JspPropertyNotWritableException) throw e;
+            throw new JspPropertyNotWritableException(this.mark, e);
+        } catch (PropertyNotFoundException e) {
+            if (e instanceof JspPropertyNotFoundException) throw e;
+            throw new JspPropertyNotFoundException(this.mark, e);
+        } catch (ELException e) {
+            if (e instanceof JspELException) throw e;
+            throw new JspELException(this.mark, e);
+        }
+    }
+
+    public Object getValue(ELContext context) throws NullPointerException,
+            PropertyNotFoundException, ELException {
+        try {
+            return this.target.getValue(context);
+        } catch (PropertyNotFoundException e) {
+            if (e instanceof JspPropertyNotFoundException) throw e;
+            throw new JspPropertyNotFoundException(this.mark, e);
+        } catch (ELException e) {
+            if (e instanceof JspELException) throw e;
+            throw new JspELException(this.mark, e);
+        }
+    }
+
+    public boolean equals(Object obj) {
+        return this.target.equals(obj);
+    }
+
+    public int hashCode() {
+        return this.target.hashCode();
+    }
+
+    public String getExpressionString() {
+        return this.target.getExpressionString();
+    }
+
+    public boolean isLiteralText() {
+        return this.target.isLiteralText();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeUTF(this.mark);
+        out.writeObject(this.target);
+    }
+
+    public void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+        this.mark = in.readUTF();
+        this.target = (ValueExpression) in.readObject();
+    }
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/VariableResolverImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/VariableResolverImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/VariableResolverImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/el/VariableResolverImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,35 @@
+/*
+ * 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.el;
+
+import javax.el.ELContext;
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.VariableResolver;
+
+public final class VariableResolverImpl implements VariableResolver {
+
+	private final ELContext ctx;
+	
+	public VariableResolverImpl(ELContext ctx) {
+		this.ctx = ctx;
+	}
+
+	public Object resolveVariable(String pName) throws ELException {
+		return this.ctx.getELResolver().getValue(this.ctx, null, pName);
+	}
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/AnnotationHelper.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/AnnotationHelper.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/AnnotationHelper.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/AnnotationHelper.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,61 @@
+/*
+ * 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.runtime;
+
+import java.lang.reflect.InvocationTargetException;
+
+import javax.naming.NamingException;
+
+import org.apache.AnnotationProcessor;
+
+
+/**
+ * Verify the annotation and Process it.
+ *
+ * @author Fabien Carrion
+ * @author Remy Maucherat
+ * @version $Revision: 467222 $, $Date: 2006-10-24 05:17:11 +0200 (Tue, 24 Oct 2006) $
+ */
+public class AnnotationHelper {
+
+    
+    /**
+     * Call postConstruct method on the specified instance. Note: In Jasper, this
+     * calls naming resources injection as well.
+     */
+    public static void postConstruct(AnnotationProcessor processor, Object instance)
+        throws IllegalAccessException, InvocationTargetException, NamingException {
+        if (processor != null) {
+            processor.processAnnotations(instance);
+            processor.postConstruct(instance);
+        }
+    }
+    
+    
+    /**
+     * Call preDestroy method on the specified instance.
+     */
+    public static void preDestroy(AnnotationProcessor processor, Object instance)
+        throws IllegalAccessException, InvocationTargetException {
+        if (processor != null) {
+            processor.preDestroy(instance);
+        }
+    }
+    
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/BodyContentImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/BodyContentImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/BodyContentImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/BodyContentImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,604 @@
+/*
+ * 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.runtime;
+
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.tagext.BodyContent;
+
+import org.apache.struts2.jasper.Constants;
+
+/**
+ * Write text to a character-output stream, buffering characters so as
+ * to provide for the efficient writing of single characters, arrays,
+ * and strings. 
+ *
+ * Provide support for discarding for the output that has been buffered. 
+ *
+ * @author Rajiv Mordani
+ * @author Jan Luehe
+ */
+public class BodyContentImpl extends BodyContent {
+    
+    private static final String LINE_SEPARATOR = 
+        System.getProperty("line.separator");
+    private static final boolean LIMIT_BUFFER = 
+        Boolean.valueOf(System.getProperty("org.apache.struts2.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "false")).booleanValue();
+    
+    private char[] cb;
+    private int nextChar;
+    private boolean closed;
+    
+    // Enclosed writer to which any output is written
+    private Writer writer;
+    
+    /**
+     * Constructor.
+     */
+    public BodyContentImpl(JspWriter enclosingWriter) {
+        super(enclosingWriter);
+        bufferSize = Constants.DEFAULT_TAG_BUFFER_SIZE;
+        cb = new char[bufferSize];
+        nextChar = 0;
+        closed = false;
+    }
+    
+    /**
+     * Write a single character.
+     */
+    public void write(int c) throws IOException {
+        if (writer != null) {
+            writer.write(c);
+        } else {
+            ensureOpen();
+            if (nextChar >= bufferSize) {
+                reAllocBuff (1);
+            }
+            cb[nextChar++] = (char) c;
+        }
+    }
+    
+    /**
+     * Write a portion of an array of characters.
+     *
+     * <p> Ordinarily this method stores characters from the given array into
+     * this stream's buffer, flushing the buffer to the underlying stream as
+     * needed.  If the requested length is at least as large as the buffer,
+     * however, then this method will flush the buffer and write the characters
+     * directly to the underlying stream.  Thus redundant
+     * <code>DiscardableBufferedWriter</code>s will not copy data
+     * unnecessarily.
+     *
+     * @param cbuf A character array
+     * @param off Offset from which to start reading characters
+     * @param len Number of characters to write
+     */
+    public void write(char[] cbuf, int off, int len) throws IOException {
+        if (writer != null) {
+            writer.write(cbuf, off, len);
+        } else {
+            ensureOpen();
+            
+            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
+                    ((off + len) > cbuf.length) || ((off + len) < 0)) {
+                throw new IndexOutOfBoundsException();
+            } else if (len == 0) {
+                return;
+            } 
+            
+            if (len >= bufferSize - nextChar)
+                reAllocBuff (len);
+            
+            System.arraycopy(cbuf, off, cb, nextChar, len);
+            nextChar+=len;
+        }
+    }
+    
+    /**
+     * Write an array of characters.  This method cannot be inherited from the
+     * Writer class because it must suppress I/O exceptions.
+     */
+    public void write(char[] buf) throws IOException {
+        if (writer != null) {
+            writer.write(buf);
+        } else {
+            write(buf, 0, buf.length);
+        }
+    }
+    
+    /**
+     * Write a portion of a String.
+     *
+     * @param s String to be written
+     * @param off Offset from which to start reading characters
+     * @param len Number of characters to be written
+     */
+    public void write(String s, int off, int len) throws IOException {
+        if (writer != null) {
+            writer.write(s, off, len);
+        } else {
+            ensureOpen();
+            if (len >= bufferSize - nextChar)
+                reAllocBuff(len);
+            
+            s.getChars(off, off + len, cb, nextChar);
+            nextChar += len;
+        }
+    }
+    
+    /**
+     * Write a string.  This method cannot be inherited from the Writer class
+     * because it must suppress I/O exceptions.
+     */
+    public void write(String s) throws IOException {
+        if (writer != null) {
+            writer.write(s);
+        } else {
+            write(s, 0, s.length());
+        }
+    }
+    
+    /**
+     * Write a line separator.  The line separator string is defined by the
+     * system property <tt>line.separator</tt>, and is not necessarily a single
+     * newline ('\n') character.
+     *
+     * @throws IOException If an I/O error occurs
+     */
+    public void newLine() throws IOException {
+        if (writer != null) {
+            writer.write(LINE_SEPARATOR);
+        } else {
+            write(LINE_SEPARATOR);
+        }
+    }
+    
+    /**
+     * Print a boolean value.  The string produced by <code>{@link
+     * java.lang.String#valueOf(boolean)}</code> is translated into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the <code>{@link
+     * #write(int)}</code> method.
+     *
+     * @param b The <code>boolean</code> to be printed
+     * @throws IOException
+     */
+    public void print(boolean b) throws IOException {
+        if (writer != null) {
+            writer.write(b ? "true" : "false");
+        } else {
+            write(b ? "true" : "false");
+        }
+    }
+    
+    /**
+     * Print a character.  The character is translated into one or more bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the <code>{@link
+     * #write(int)}</code> method.
+     *
+     * @param c The <code>char</code> to be printed
+     * @throws IOException
+     */
+    public void print(char c) throws IOException {
+        if (writer != null) {
+            writer.write(String.valueOf(c));
+        } else {
+            write(String.valueOf(c));
+        }
+    }
+    
+    /**
+     * Print an integer.  The string produced by <code>{@link
+     * java.lang.String#valueOf(int)}</code> is translated into bytes according
+     * to the platform's default character encoding, and these bytes are
+     * written in exactly the manner of the <code>{@link #write(int)}</code>
+     * method.
+     *
+     * @param i The <code>int</code> to be printed
+     * @throws IOException
+     */
+    public void print(int i) throws IOException {
+        if (writer != null) {
+            writer.write(String.valueOf(i));
+        } else {
+            write(String.valueOf(i));
+        }
+    }
+    
+    /**
+     * Print a long integer.  The string produced by <code>{@link
+     * java.lang.String#valueOf(long)}</code> is translated into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the
+     * <code>{@link #write(int)}</code> method.
+     *
+     * @param l The <code>long</code> to be printed
+     * @throws IOException
+     */
+    public void print(long l) throws IOException {
+        if (writer != null) {
+            writer.write(String.valueOf(l));
+        } else {
+            write(String.valueOf(l));
+        }
+    }
+    
+    /**
+     * Print a floating-point number.  The string produced by <code>{@link
+     * java.lang.String#valueOf(float)}</code> is translated into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the
+     * <code>{@link #write(int)}</code> method.
+     *
+     * @param f The <code>float</code> to be printed
+     * @throws IOException
+     */
+    public void print(float f) throws IOException {
+        if (writer != null) {
+            writer.write(String.valueOf(f));
+        } else {
+            write(String.valueOf(f));
+        }
+    }
+    
+    /**
+     * Print a double-precision floating-point number.  The string produced by
+     * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
+     * bytes according to the platform's default character encoding, and these
+     * bytes are written in exactly the manner of the <code>{@link
+     * #write(int)}</code> method.
+     *
+     * @param d The <code>double</code> to be printed
+     * @throws IOException
+     */
+    public void print(double d) throws IOException {
+        if (writer != null) {
+            writer.write(String.valueOf(d));
+        } else {
+            write(String.valueOf(d));
+        }
+    }
+    
+    /**
+     * Print an array of characters.  The characters are converted into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the
+     * <code>{@link #write(int)}</code> method.
+     *
+     * @param s The array of chars to be printed
+     *
+     * @throws NullPointerException If <code>s</code> is <code>null</code>
+     * @throws IOException
+     */
+    public void print(char[] s) throws IOException {
+        if (writer != null) {
+            writer.write(s);
+        } else {
+            write(s);
+        }
+    }
+    
+    /**
+     * Print a string.  If the argument is <code>null</code> then the string
+     * <code>"null"</code> is printed.  Otherwise, the string's characters are
+     * converted into bytes according to the platform's default character
+     * encoding, and these bytes are written in exactly the manner of the
+     * <code>{@link #write(int)}</code> method.
+     *
+     * @param s The <code>String</code> to be printed
+     * @throws IOException
+     */
+    public void print(String s) throws IOException {
+        if (s == null) s = "null";
+        if (writer != null) {
+            writer.write(s);
+        } else {
+            write(s);
+        }
+    }
+    
+    /**
+     * Print an object.  The string produced by the <code>{@link
+     * java.lang.String#valueOf(Object)}</code> method is translated into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the
+     * <code>{@link #write(int)}</code> method.
+     *
+     * @param obj The <code>Object</code> to be printed
+     * @throws IOException
+     */
+    public void print(Object obj) throws IOException {
+        if (writer != null) {
+            writer.write(String.valueOf(obj));
+        } else {
+            write(String.valueOf(obj));
+        }
+    }
+    
+    /**
+     * Terminate the current line by writing the line separator string.  The
+     * line separator string is defined by the system property
+     * <code>line.separator</code>, and is not necessarily a single newline
+     * character (<code>'\n'</code>).
+     *
+     * @throws IOException
+     */
+    public void println() throws IOException {
+        newLine();
+    }
+    
+    /**
+     * Print a boolean value and then terminate the line.  This method behaves
+     * as though it invokes <code>{@link #print(boolean)}</code> and then
+     * <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(boolean x) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print a character and then terminate the line.  This method behaves as
+     * though it invokes <code>{@link #print(char)}</code> and then
+     * <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(char x) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print an integer and then terminate the line.  This method behaves as
+     * though it invokes <code>{@link #print(int)}</code> and then
+     * <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(int x) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print a long integer and then terminate the line.  This method behaves
+     * as though it invokes <code>{@link #print(long)}</code> and then
+     * <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(long x) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print a floating-point number and then terminate the line.  This method
+     * behaves as though it invokes <code>{@link #print(float)}</code> and then
+     * <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(float x) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print a double-precision floating-point number and then terminate the
+     * line.  This method behaves as though it invokes <code>{@link
+     * #print(double)}</code> and then <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(double x) throws IOException{
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print an array of characters and then terminate the line.  This method
+     * behaves as though it invokes <code>{@link #print(char[])}</code> and
+     * then <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(char x[]) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print a String and then terminate the line.  This method behaves as
+     * though it invokes <code>{@link #print(String)}</code> and then
+     * <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(String x) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Print an Object and then terminate the line.  This method behaves as
+     * though it invokes <code>{@link #print(Object)}</code> and then
+     * <code>{@link #println()}</code>.
+     *
+     * @throws IOException
+     */
+    public void println(Object x) throws IOException {
+        print(x);
+        println();
+    }
+    
+    /**
+     * Clear the contents of the buffer. If the buffer has been already
+     * been flushed then the clear operation shall throw an IOException
+     * to signal the fact that some data has already been irrevocably 
+     * written to the client response stream.
+     *
+     * @throws IOException If an I/O error occurs
+     */
+    public void clear() throws IOException {
+        if (writer != null) {
+            throw new IOException();
+        } else {
+            nextChar = 0;
+            if (LIMIT_BUFFER && (cb.length > Constants.DEFAULT_TAG_BUFFER_SIZE)) {
+                bufferSize = Constants.DEFAULT_TAG_BUFFER_SIZE;
+                cb = new char[bufferSize];
+            }
+        }
+    }
+    
+    /**
+     * Clears the current contents of the buffer. Unlike clear(), this
+     * mehtod will not throw an IOException if the buffer has already been
+     * flushed. It merely clears the current content of the buffer and
+     * returns.
+     *
+     * @throws IOException If an I/O error occurs
+     */
+    public void clearBuffer() throws IOException {
+        if (writer == null) {
+            this.clear();
+        }
+    }
+    
+    /**
+     * Close the stream, flushing it first.  Once a stream has been closed,
+     * further write() or flush() invocations will cause an IOException to be
+     * thrown.  Closing a previously-closed stream, however, has no effect.
+     *
+     * @throws IOException If an I/O error occurs
+     */
+    public void close() throws IOException {
+        if (writer != null) {
+            writer.close();
+        } else {
+            closed = true;
+        }
+    }
+    
+    /**
+     * This method returns the size of the buffer used by the JspWriter.
+     *
+     * @return the size of the buffer in bytes, or 0 is unbuffered.
+     */
+    public int getBufferSize() {
+        // According to the spec, the JspWriter returned by 
+        // JspContext.pushBody(java.io.Writer writer) must behave as
+        // though it were unbuffered. This means that its getBufferSize()
+        // must always return 0.
+        return (writer == null) ? bufferSize : 0;
+    }
+    
+    /**
+     * @return the number of bytes unused in the buffer
+     */
+    public int getRemaining() {
+        return (writer == null) ? bufferSize-nextChar : 0;
+    }
+    
+    /**
+     * Return the value of this BodyJspWriter as a Reader.
+     * Note: this is after evaluation!!  There are no scriptlets,
+     * etc in this stream.
+     *
+     * @return the value of this BodyJspWriter as a Reader
+     */
+    public Reader getReader() {
+        return (writer == null) ? new CharArrayReader (cb, 0, nextChar) : null;
+    }
+    
+    /**
+     * Return the value of the BodyJspWriter as a String.
+     * Note: this is after evaluation!!  There are no scriptlets,
+     * etc in this stream.
+     *
+     * @return the value of the BodyJspWriter as a String
+     */
+    public String getString() {
+        return (writer == null) ? new String(cb, 0, nextChar) : null;
+    }
+    
+    /**
+     * Write the contents of this BodyJspWriter into a Writer.
+     * Subclasses are likely to do interesting things with the
+     * implementation so some things are extra efficient.
+     *
+     * @param out The writer into which to place the contents of this body
+     * evaluation
+     */
+    public void writeOut(Writer out) throws IOException {
+        if (writer == null) {
+            out.write(cb, 0, nextChar);
+            // Flush not called as the writer passed could be a BodyContent and
+            // it doesn't allow to flush.
+        }
+    }
+    
+    /**
+     * Sets the writer to which all output is written.
+     */
+    void setWriter(Writer writer) {
+        this.writer = writer;
+        closed = false;
+        if (writer == null) {
+            clearBody();
+        }
+    }
+    
+    private void ensureOpen() throws IOException {
+        if (closed) throw new IOException("Stream closed");
+    }
+    
+    /**
+     * Reallocates buffer since the spec requires it to be unbounded.
+     */
+    private void reAllocBuff(int len) {
+        
+        if (bufferSize + len <= cb.length) {
+            bufferSize = cb.length;
+            return;
+        }
+        
+        if (len < cb.length) {
+            len = cb.length;
+        }
+        
+        bufferSize = cb.length + len;
+        char[] tmp = new char[bufferSize];
+        
+        System.arraycopy(cb, 0, tmp, 0, cb.length);
+        cb = tmp;
+        tmp = null;
+        
+    }
+    
+    
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,88 @@
+/*
+ * 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.runtime;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.HttpJspPage;
+import javax.servlet.jsp.JspFactory;
+
+import org.apache.struts2.jasper.compiler.Localizer;
+
+/**
+ * This is the super class of all JSP-generated servlets.
+ *
+ * @author Anil K. Vijendran
+ */
+public abstract class HttpJspBase 
+    extends HttpServlet 
+    implements HttpJspPage 
+        
+    
+{
+    
+    protected HttpJspBase() {
+    }
+
+    public final void init(ServletConfig config) 
+	throws ServletException 
+    {
+        super.init(config);
+	jspInit();
+        _jspInit();
+    }
+    
+    public String getServletInfo() {
+	return Localizer.getMessage("jsp.engine.info");
+    }
+
+    public final void destroy() {
+	jspDestroy();
+	_jspDestroy();
+    }
+
+    /**
+     * Entry point into service.
+     */
+    public final void service(HttpServletRequest request, HttpServletResponse response) 
+	throws ServletException, IOException 
+    {
+        _jspService(request, response);
+    }
+    
+    public void jspInit() {
+    }
+
+    public void _jspInit() {
+    }
+
+    public void jspDestroy() {
+    }
+
+    protected void _jspDestroy() {
+    }
+
+    public abstract void _jspService(HttpServletRequest request, 
+				     HttpServletResponse response) 
+	throws ServletException, IOException;
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspApplicationContextImpl.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspApplicationContextImpl.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspApplicationContextImpl.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspApplicationContextImpl.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,138 @@
+/*
+ * 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.runtime;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContextEvent;
+import javax.el.ELContextListener;
+import javax.el.ELResolver;
+import javax.el.ExpressionFactory;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.ResourceBundleELResolver;
+import javax.servlet.ServletContext;
+import javax.servlet.jsp.JspApplicationContext;
+import javax.servlet.jsp.JspContext;
+import javax.servlet.jsp.el.ImplicitObjectELResolver;
+import javax.servlet.jsp.el.ScopedAttributeELResolver;
+
+import org.apache.struts2.el.ExpressionFactoryImpl;
+import org.apache.struts2.jasper.el.ELContextImpl;
+
+/**
+ * Implementation of JspApplicationContext
+ * 
+ * @author Jacob Hookom
+ */
+public class JspApplicationContextImpl implements JspApplicationContext {
+
+	private final static String KEY = JspApplicationContextImpl.class.getName();
+
+	private final static ExpressionFactory expressionFactory = new ExpressionFactoryImpl();
+
+	private final List<ELContextListener> contextListeners = new ArrayList<ELContextListener>();
+
+	private final List<ELResolver> resolvers = new ArrayList<ELResolver>();
+
+	private boolean instantiated = false;
+
+	private ELResolver resolver;
+
+	public JspApplicationContextImpl() {
+
+	}
+
+	public void addELContextListener(ELContextListener listener) {
+		if (listener == null) {
+			throw new IllegalArgumentException("ELConextListener was null");
+		}
+		this.contextListeners.add(listener);
+	}
+
+	public static JspApplicationContextImpl getInstance(ServletContext context) {
+		if (context == null) {
+			throw new IllegalArgumentException("ServletContext was null");
+		}
+		JspApplicationContextImpl impl = (JspApplicationContextImpl) context
+				.getAttribute(KEY);
+		if (impl == null) {
+			impl = new JspApplicationContextImpl();
+			context.setAttribute(KEY, impl);
+		}
+		return impl;
+	}
+
+	public ELContextImpl createELContext(JspContext context) {
+		if (context == null) {
+			throw new IllegalArgumentException("JspContext was null");
+		}
+
+		// create ELContext for JspContext
+		ELResolver r = this.createELResolver();
+		ELContextImpl ctx = new ELContextImpl(r);
+		ctx.putContext(JspContext.class, context);
+
+		// alert all ELContextListeners
+		ELContextEvent event = new ELContextEvent(ctx);
+		for (int i = 0; i < this.contextListeners.size(); i++) {
+			this.contextListeners.get(i).contextCreated(event);
+		}
+
+		return ctx;
+	}
+
+	private ELResolver createELResolver() {
+		this.instantiated = true;
+		if (this.resolver == null) {
+			CompositeELResolver r = new CompositeELResolver();
+			r.add(new ImplicitObjectELResolver());
+			for (Iterator itr = this.resolvers.iterator(); itr.hasNext();) {
+				r.add((ELResolver) itr.next());
+			}
+			r.add(new MapELResolver());
+			r.add(new ResourceBundleELResolver());
+			r.add(new ListELResolver());
+			r.add(new ArrayELResolver());	
+			r.add(new BeanELResolver());
+			r.add(new ScopedAttributeELResolver());
+			this.resolver = r;
+		}
+		return this.resolver;
+	}
+
+	public void addELResolver(ELResolver resolver) throws IllegalStateException {
+		if (resolver == null) {
+			throw new IllegalArgumentException("ELResolver was null");
+		}
+		if (this.instantiated) {
+			throw new IllegalStateException(
+					"cannot call addELResolver after the first request has been made");
+		}
+		this.resolvers.add(resolver);
+	}
+
+	public ExpressionFactory getExpressionFactory() {
+		return expressionFactory;
+	}
+
+}

Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,462 @@
+/*
+ * 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.runtime;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.jsp.JspContext;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.ExpressionEvaluator;
+import javax.servlet.jsp.el.VariableResolver;
+import javax.servlet.jsp.tagext.BodyContent;
+import javax.servlet.jsp.tagext.VariableInfo;
+
+import org.apache.struts2.jasper.compiler.Localizer;
+import org.apache.struts2.jasper.util.Enumerator;
+
+/**
+ * Implementation of a JSP Context Wrapper.
+ * 
+ * The JSP Context Wrapper is a JspContext created and maintained by a tag
+ * handler implementation. It wraps the Invoking JSP Context, that is, the
+ * JspContext instance passed to the tag handler by the invoking page via
+ * setJspContext().
+ * 
+ * @author Kin-man Chung
+ * @author Jan Luehe
+ * @author Jacob Hookom
+ */
+public class JspContextWrapper extends PageContext implements VariableResolver {
+
+	// Invoking JSP context
+	private PageContext invokingJspCtxt;
+
+	private transient HashMap<String, Object> pageAttributes;
+
+	// ArrayList of NESTED scripting variables
+	private ArrayList nestedVars;
+
+	// ArrayList of AT_BEGIN scripting variables
+	private ArrayList atBeginVars;
+
+	// ArrayList of AT_END scripting variables
+	private ArrayList atEndVars;
+
+	private Map aliases;
+
+	private HashMap<String, Object> originalNestedVars;
+
+	public JspContextWrapper(JspContext jspContext, ArrayList nestedVars,
+			ArrayList atBeginVars, ArrayList atEndVars, Map aliases) {
+		this.invokingJspCtxt = (PageContext) jspContext;
+		this.nestedVars = nestedVars;
+		this.atBeginVars = atBeginVars;
+		this.atEndVars = atEndVars;
+		this.pageAttributes = new HashMap<String, Object>(16);
+		this.aliases = aliases;
+
+		if (nestedVars != null) {
+			this.originalNestedVars = new HashMap<String, Object>(nestedVars.size());
+		}
+		syncBeginTagFile();
+	}
+
+	public void initialize(Servlet servlet, ServletRequest request,
+			ServletResponse response, String errorPageURL,
+			boolean needsSession, int bufferSize, boolean autoFlush)
+			throws IOException, IllegalStateException, IllegalArgumentException {
+	}
+
+	public Object getAttribute(String name) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		return pageAttributes.get(name);
+	}
+
+	public Object getAttribute(String name, int scope) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		if (scope == PAGE_SCOPE) {
+			return pageAttributes.get(name);
+		}
+
+		return invokingJspCtxt.getAttribute(name, scope);
+	}
+
+	public void setAttribute(String name, Object value) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		if (value != null) {
+			pageAttributes.put(name, value);
+		} else {
+			removeAttribute(name, PAGE_SCOPE);
+		}
+	}
+
+	public void setAttribute(String name, Object value, int scope) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		if (scope == PAGE_SCOPE) {
+			if (value != null) {
+				pageAttributes.put(name, value);
+			} else {
+				removeAttribute(name, PAGE_SCOPE);
+			}
+		} else {
+			invokingJspCtxt.setAttribute(name, value, scope);
+		}
+	}
+
+	public Object findAttribute(String name) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		Object o = pageAttributes.get(name);
+		if (o == null) {
+			o = invokingJspCtxt.getAttribute(name, REQUEST_SCOPE);
+			if (o == null) {
+				if (getSession() != null) {
+					o = invokingJspCtxt.getAttribute(name, SESSION_SCOPE);
+				}
+				if (o == null) {
+					o = invokingJspCtxt.getAttribute(name, APPLICATION_SCOPE);
+				}
+			}
+		}
+
+		return o;
+	}
+
+	public void removeAttribute(String name) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		pageAttributes.remove(name);
+		invokingJspCtxt.removeAttribute(name, REQUEST_SCOPE);
+		if (getSession() != null) {
+			invokingJspCtxt.removeAttribute(name, SESSION_SCOPE);
+		}
+		invokingJspCtxt.removeAttribute(name, APPLICATION_SCOPE);
+	}
+
+	public void removeAttribute(String name, int scope) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		if (scope == PAGE_SCOPE) {
+			pageAttributes.remove(name);
+		} else {
+			invokingJspCtxt.removeAttribute(name, scope);
+		}
+	}
+
+	public int getAttributesScope(String name) {
+
+		if (name == null) {
+			throw new NullPointerException(Localizer
+					.getMessage("jsp.error.attribute.null_name"));
+		}
+
+		if (pageAttributes.get(name) != null) {
+			return PAGE_SCOPE;
+		} else {
+			return invokingJspCtxt.getAttributesScope(name);
+		}
+	}
+
+	public Enumeration<String> getAttributeNamesInScope(int scope) {
+		if (scope == PAGE_SCOPE) {
+			return new Enumerator(pageAttributes.keySet().iterator());
+		}
+
+		return invokingJspCtxt.getAttributeNamesInScope(scope);
+	}
+
+	public void release() {
+		invokingJspCtxt.release();
+	}
+
+	public JspWriter getOut() {
+		return invokingJspCtxt.getOut();
+	}
+
+	public HttpSession getSession() {
+		return invokingJspCtxt.getSession();
+	}
+
+	public Object getPage() {
+		return invokingJspCtxt.getPage();
+	}
+
+	public ServletRequest getRequest() {
+		return invokingJspCtxt.getRequest();
+	}
+
+	public ServletResponse getResponse() {
+		return invokingJspCtxt.getResponse();
+	}
+
+	public Exception getException() {
+		return invokingJspCtxt.getException();
+	}
+
+	public ServletConfig getServletConfig() {
+		return invokingJspCtxt.getServletConfig();
+	}
+
+	public ServletContext getServletContext() {
+		return invokingJspCtxt.getServletContext();
+	}
+
+	public void forward(String relativeUrlPath) throws ServletException,
+			IOException {
+		invokingJspCtxt.forward(relativeUrlPath);
+	}
+
+	public void include(String relativeUrlPath) throws ServletException,
+			IOException {
+		invokingJspCtxt.include(relativeUrlPath);
+	}
+
+	public void include(String relativeUrlPath, boolean flush)
+			throws ServletException, IOException {
+		invokingJspCtxt.include(relativeUrlPath, false);
+	}
+
+	public VariableResolver getVariableResolver() {
+		return this;
+	}
+
+	public BodyContent pushBody() {
+		return invokingJspCtxt.pushBody();
+	}
+
+	public JspWriter pushBody(Writer writer) {
+		return invokingJspCtxt.pushBody(writer);
+	}
+
+	public JspWriter popBody() {
+		return invokingJspCtxt.popBody();
+	}
+
+	public ExpressionEvaluator getExpressionEvaluator() {
+		return invokingJspCtxt.getExpressionEvaluator();
+	}
+
+	public void handlePageException(Exception ex) throws IOException,
+			ServletException {
+		// Should never be called since handleException() called with a
+		// Throwable in the generated servlet.
+		handlePageException((Throwable) ex);
+	}
+
+	public void handlePageException(Throwable t) throws IOException,
+			ServletException {
+		invokingJspCtxt.handlePageException(t);
+	}
+
+	/**
+	 * VariableResolver interface
+	 */
+	public Object resolveVariable(String pName) throws ELException {
+		ELContext ctx = this.getELContext();
+		return ctx.getELResolver().getValue(ctx, null, pName);
+	}
+
+	/**
+	 * Synchronize variables at begin of tag file
+	 */
+	public void syncBeginTagFile() {
+		saveNestedVariables();
+	}
+
+	/**
+	 * Synchronize variables before fragment invokation
+	 */
+	public void syncBeforeInvoke() {
+		copyTagToPageScope(VariableInfo.NESTED);
+		copyTagToPageScope(VariableInfo.AT_BEGIN);
+	}
+
+	/**
+	 * Synchronize variables at end of tag file
+	 */
+	public void syncEndTagFile() {
+		copyTagToPageScope(VariableInfo.AT_BEGIN);
+		copyTagToPageScope(VariableInfo.AT_END);
+		restoreNestedVariables();
+	}
+
+	/**
+	 * Copies the variables of the given scope from the virtual page scope of
+	 * this JSP context wrapper to the page scope of the invoking JSP context.
+	 * 
+	 * @param scope
+	 *            variable scope (one of NESTED, AT_BEGIN, or AT_END)
+	 */
+	private void copyTagToPageScope(int scope) {
+		Iterator iter = null;
+
+		switch (scope) {
+		case VariableInfo.NESTED:
+			if (nestedVars != null) {
+				iter = nestedVars.iterator();
+			}
+			break;
+		case VariableInfo.AT_BEGIN:
+			if (atBeginVars != null) {
+				iter = atBeginVars.iterator();
+			}
+			break;
+		case VariableInfo.AT_END:
+			if (atEndVars != null) {
+				iter = atEndVars.iterator();
+			}
+			break;
+		}
+
+		while ((iter != null) && iter.hasNext()) {
+			String varName = (String) iter.next();
+			Object obj = getAttribute(varName);
+			varName = findAlias(varName);
+			if (obj != null) {
+				invokingJspCtxt.setAttribute(varName, obj);
+			} else {
+				invokingJspCtxt.removeAttribute(varName, PAGE_SCOPE);
+			}
+		}
+	}
+
+	/**
+	 * Saves the values of any NESTED variables that are present in the invoking
+	 * JSP context, so they can later be restored.
+	 */
+	private void saveNestedVariables() {
+		if (nestedVars != null) {
+			Iterator iter = nestedVars.iterator();
+			while (iter.hasNext()) {
+				String varName = (String) iter.next();
+				varName = findAlias(varName);
+				Object obj = invokingJspCtxt.getAttribute(varName);
+				if (obj != null) {
+					originalNestedVars.put(varName, obj);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Restores the values of any NESTED variables in the invoking JSP context.
+	 */
+	private void restoreNestedVariables() {
+		if (nestedVars != null) {
+			Iterator iter = nestedVars.iterator();
+			while (iter.hasNext()) {
+				String varName = (String) iter.next();
+				varName = findAlias(varName);
+				Object obj = originalNestedVars.get(varName);
+				if (obj != null) {
+					invokingJspCtxt.setAttribute(varName, obj);
+				} else {
+					invokingJspCtxt.removeAttribute(varName, PAGE_SCOPE);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Checks to see if the given variable name is used as an alias, and if so,
+	 * returns the variable name for which it is used as an alias.
+	 * 
+	 * @param varName
+	 *            The variable name to check
+	 * @return The variable name for which varName is used as an alias, or
+	 *         varName if it is not being used as an alias
+	 */
+	private String findAlias(String varName) {
+
+		if (aliases == null)
+			return varName;
+
+		String alias = (String) aliases.get(varName);
+		if (alias == null) {
+			return varName;
+		}
+		return alias;
+	}
+
+	//private ELContextImpl elContext;
+
+	public ELContext getELContext() {
+        // instead decorate!!!
+        
+        return this.invokingJspCtxt.getELContext();
+        
+        /*
+		if (this.elContext != null) {
+			JspFactory jspFact = JspFactory.getDefaultFactory();
+			ServletContext servletContext = this.getServletContext();
+			JspApplicationContextImpl jspCtx = (JspApplicationContextImpl) jspFact
+					.getJspApplicationContext(servletContext);
+			this.elContext = jspCtx.createELContext(this);
+		}
+		return this.elContext;
+        */
+	}
+}