| /* |
| * 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 freemarker.ext.jsp; |
| |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| |
| import javax.el.ArrayELResolver; |
| import javax.el.BeanELResolver; |
| import javax.el.CompositeELResolver; |
| import javax.el.ELContext; |
| import javax.el.ELContextEvent; |
| import javax.el.ELContextListener; |
| import javax.el.ELResolver; |
| import javax.el.ExpressionFactory; |
| import javax.el.FunctionMapper; |
| import javax.el.ListELResolver; |
| import javax.el.MapELResolver; |
| import javax.el.ResourceBundleELResolver; |
| import javax.el.ValueExpression; |
| import javax.el.VariableMapper; |
| import javax.servlet.jsp.JspApplicationContext; |
| import javax.servlet.jsp.el.ImplicitObjectELResolver; |
| import javax.servlet.jsp.el.ScopedAttributeELResolver; |
| |
| import freemarker.log.Logger; |
| import freemarker.template.utility.ClassUtil; |
| |
| /** |
| */ |
| class FreeMarkerJspApplicationContext implements JspApplicationContext { |
| private static final Logger LOG = Logger.getLogger("freemarker.jsp"); |
| private static final ExpressionFactory expressionFactoryImpl = findExpressionFactoryImplementation(); |
| |
| private final LinkedList listeners = new LinkedList(); |
| private final CompositeELResolver elResolver = new CompositeELResolver(); |
| private final CompositeELResolver additionalResolvers = new CompositeELResolver(); |
| { |
| elResolver.add(new ImplicitObjectELResolver()); |
| elResolver.add(additionalResolvers); |
| elResolver.add(new MapELResolver()); |
| elResolver.add(new ResourceBundleELResolver()); |
| elResolver.add(new ListELResolver()); |
| elResolver.add(new ArrayELResolver()); |
| elResolver.add(new BeanELResolver()); |
| elResolver.add(new ScopedAttributeELResolver()); |
| } |
| |
| public void addELContextListener(ELContextListener listener) { |
| synchronized (listeners) { |
| listeners.addLast(listener); |
| } |
| } |
| |
| private static ExpressionFactory findExpressionFactoryImplementation() { |
| ExpressionFactory ef = tryExpressionFactoryImplementation("com.sun"); |
| if (ef == null) { |
| ef = tryExpressionFactoryImplementation("org.apache"); |
| if (ef == null) { |
| LOG.warn("Could not find any implementation for " + |
| ExpressionFactory.class.getName()); |
| } |
| } |
| return ef; |
| } |
| |
| private static ExpressionFactory tryExpressionFactoryImplementation(String packagePrefix) { |
| String className = packagePrefix + ".el.ExpressionFactoryImpl"; |
| try { |
| Class cl = ClassUtil.forName(className); |
| if (ExpressionFactory.class.isAssignableFrom(cl)) { |
| LOG.info("Using " + className + " as implementation of " + |
| ExpressionFactory.class.getName()); |
| return (ExpressionFactory) cl.newInstance(); |
| } |
| LOG.warn("Class " + className + " does not implement " + |
| ExpressionFactory.class.getName()); |
| } catch (ClassNotFoundException e) { |
| } catch (Exception e) { |
| LOG.error("Failed to instantiate " + className, e); |
| } |
| return null; |
| } |
| |
| public void addELResolver(ELResolver resolver) { |
| additionalResolvers.add(resolver); |
| } |
| |
| public ExpressionFactory getExpressionFactory() { |
| return expressionFactoryImpl; |
| } |
| |
| ELContext createNewELContext(final FreeMarkerPageContext pageCtx) { |
| ELContext ctx = new FreeMarkerELContext(pageCtx); |
| ELContextEvent event = new ELContextEvent(ctx); |
| synchronized (listeners) { |
| for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { |
| ELContextListener l = (ELContextListener) iter.next(); |
| l.contextCreated(event); |
| } |
| } |
| return ctx; |
| } |
| |
| private class FreeMarkerELContext extends ELContext { |
| private final FreeMarkerPageContext pageCtx; |
| |
| FreeMarkerELContext(FreeMarkerPageContext pageCtx) { |
| this.pageCtx = pageCtx; |
| } |
| |
| @Override |
| public ELResolver getELResolver() { |
| return elResolver; |
| } |
| |
| @Override |
| public FunctionMapper getFunctionMapper() { |
| return null; |
| } |
| |
| @Override |
| public VariableMapper getVariableMapper() { |
| return new VariableMapper() { |
| @Override |
| public ValueExpression resolveVariable(String name) { |
| Object obj = pageCtx.findAttribute(name); |
| if (obj == null) { |
| return null; |
| } |
| return expressionFactoryImpl.createValueExpression(obj, |
| obj.getClass()); |
| } |
| |
| @Override |
| public ValueExpression setVariable(String name, |
| ValueExpression value) { |
| ValueExpression prev = resolveVariable(name); |
| pageCtx.setAttribute(name, value.getValue( |
| FreeMarkerELContext.this)); |
| return prev; |
| } |
| }; |
| } |
| } |
| } |