001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.scxml.env.jsp;
018    
019    import java.io.IOException;
020    import java.io.NotSerializableException;
021    import java.io.ObjectInputStream;
022    import java.io.ObjectOutputStream;
023    
024    import javax.servlet.jsp.JspContext;
025    import javax.servlet.jsp.el.ELException;
026    import javax.servlet.jsp.el.VariableResolver;
027    
028    /**
029     * EL Context for root SCXML element. Wrapper around the host JSP context.
030     * Must treat variables in the host JSP environments as read-only.
031     *
032     */
033    public final class RootContext extends ELContext {
034    
035        /** Host JSP's VariableResolver. */
036        private VariableResolver variableResolver;
037        /** Bark if JSP Context is null. */
038        private static final String ERR_HOST_JSP_CTX_NULL =
039            "Host JSP Context cannot be null";
040    
041        /**
042         * Constructor.
043         *
044         * @param ctx the host JspContext
045         */
046        public RootContext(final JspContext ctx) {
047            super();
048            if (ctx == null) {
049                getLog().error(ERR_HOST_JSP_CTX_NULL);
050                throw new IllegalArgumentException(ERR_HOST_JSP_CTX_NULL);
051            } else {
052              // only retain the VariableResolver
053              this.variableResolver = ctx.getVariableResolver();
054            }
055        }
056    
057        /**
058         * Get the value of the given variable in this Context.
059         *
060         * @param name The name of the variable
061         * @return The value (or null)
062         * @see org.apache.commons.scxml.Context#get(java.lang.String)
063         */
064        public Object get(final String name) {
065            Object value = super.get(name);
066            if (value == null) {
067                try {
068                    value = variableResolver.resolveVariable(name);
069                } catch (ELException ele) {
070                    getLog().error(ele.getMessage(), ele);
071                }
072            }
073            return value;
074        }
075    
076        /**
077         * Does the given variable exist in this Context.
078         *
079         * @param name The name of the variable
080         * @return boolean true if the variable exists
081         * @see org.apache.commons.scxml.Context#has(java.lang.String)
082         */
083        public boolean has(final String name) {
084            boolean exists = super.has(name);
085            Object value = null;
086            if (!exists) {
087                try {
088                    value = variableResolver.resolveVariable(name);
089                } catch (ELException ele) {
090                    getLog().error(ele.getMessage(), ele);
091                }
092                if (value != null) {
093                    exists = true;
094                }
095            }
096            return exists;
097        }
098    
099        /**
100         * Get the VariableResolver associated with this root context.
101         *
102         * @return Returns the variableResolver.
103         */
104        public VariableResolver getVariableResolver() {
105            return variableResolver;
106        }
107    
108        /**
109         * Set the VariableResolver associated with this root context.
110         *
111         * @param variableResolver The variableResolver to set.
112         */
113        public void setVariableResolver(final VariableResolver variableResolver) {
114            this.variableResolver = variableResolver;
115        }
116    
117        //--------------------------------------------------- Truth in advertising
118    
119        /**
120         * Instances of this class are not serializable.
121         *
122         * @param out The object output stream.
123         * @throws IOException Guaranteed to throw a NotSerializableException
124         */
125        private void writeObject(final ObjectOutputStream out)
126        throws IOException {
127            throw new NotSerializableException();
128        }
129    
130        /**
131         * Instances of this class are not serializable.
132         *
133         * @param in The object input stream.
134         * @throws IOException Guaranteed to throw a NotSerializableException
135         */
136        private void readObject(final ObjectInputStream in)
137        throws IOException {
138            throw new NotSerializableException();
139        }
140    
141    }
142