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    
018    package javax.servlet.jsp.el;
019    
020    import java.beans.FeatureDescriptor;
021    import java.util.AbstractMap;
022    import java.util.ArrayList;
023    import java.util.Arrays;
024    import java.util.Enumeration;
025    import java.util.HashSet;
026    import java.util.Iterator;
027    import java.util.List;
028    import java.util.Map;
029    import java.util.Set;
030    import java.util.Vector;
031    
032    import javax.el.ELContext;
033    import javax.el.ELException;
034    import javax.el.ELResolver;
035    import javax.el.PropertyNotFoundException;
036    import javax.el.PropertyNotWritableException;
037    import javax.servlet.http.Cookie;
038    import javax.servlet.http.HttpServletRequest;
039    import javax.servlet.http.HttpSession;
040    import javax.servlet.jsp.JspContext;
041    import javax.servlet.jsp.PageContext;
042    
043    /**
044     *
045     * @since 2.1
046     */
047    public class ImplicitObjectELResolver extends ELResolver {
048    
049        private final static String[] SCOPE_NAMES = new String[] {
050                "applicationScope", "cookie", "header", "headerValues",
051                "initParam", "pageContext", "pageScope", "param", "paramValues",
052                "requestScope", "sessionScope" };
053    
054        private final static int APPLICATIONSCOPE = 0;
055    
056        private final static int COOKIE = 1;
057    
058        private final static int HEADER = 2;
059    
060        private final static int HEADERVALUES = 3;
061    
062        private final static int INITPARAM = 4;
063    
064        private final static int PAGECONTEXT = 5;
065    
066        private final static int PAGESCOPE = 6;
067    
068        private final static int PARAM = 7;
069    
070        private final static int PARAM_VALUES = 8;
071    
072        private final static int REQUEST_SCOPE = 9;
073    
074        private final static int SESSION_SCOPE = 10;
075    
076        public ImplicitObjectELResolver() {
077            super();
078        }
079    
080        public Object getValue(ELContext context, Object base, Object property)
081                throws NullPointerException, PropertyNotFoundException, ELException {
082            if (context == null) {
083                throw new NullPointerException();
084            }
085    
086            if (base == null && property != null) {
087                int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
088    
089                if (idx >= 0) {
090                    PageContext page = (PageContext) context
091                            .getContext(JspContext.class);
092                    context.setPropertyResolved(true);
093                    switch (idx) {
094                    case APPLICATIONSCOPE:
095                        return ScopeManager.get(page).getApplicationScope();
096                    case COOKIE:
097                        return ScopeManager.get(page).getCookie();
098                    case HEADER:
099                        return ScopeManager.get(page).getHeader();
100                    case HEADERVALUES:
101                        return ScopeManager.get(page).getHeaderValues();
102                    case INITPARAM:
103                        return ScopeManager.get(page).getInitParam();
104                    case PAGECONTEXT:
105                        return ScopeManager.get(page).getPageContext();
106                    case PAGESCOPE:
107                        return ScopeManager.get(page).getPageScope();
108                    case PARAM:
109                        return ScopeManager.get(page).getParam();
110                    case PARAM_VALUES:
111                        return ScopeManager.get(page).getParamValues();
112                    case REQUEST_SCOPE:
113                        return ScopeManager.get(page).getRequestScope();
114                    case SESSION_SCOPE:
115                        return ScopeManager.get(page).getSessionScope();
116                    }
117                }
118            }
119            return null;
120        }
121    
122        public Class getType(ELContext context, Object base, Object property)
123                throws NullPointerException, PropertyNotFoundException, ELException {
124            if (context == null) {
125                throw new NullPointerException();
126            }
127    
128            if (base == null && property != null) {
129                int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
130                if (idx >= 0) {
131                    context.setPropertyResolved(true);
132                }
133            }
134            return null;
135        }
136    
137        public void setValue(ELContext context, Object base, Object property,
138                Object value) throws NullPointerException,
139                PropertyNotFoundException, PropertyNotWritableException,
140                ELException {
141            if (context == null) {
142                throw new NullPointerException();
143            }
144    
145            if (base == null && property != null) {
146                int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
147                if (idx >= 0) {
148                    context.setPropertyResolved(true);
149                    throw new PropertyNotWritableException();
150                }
151            }
152        }
153    
154        public boolean isReadOnly(ELContext context, Object base, Object property)
155                throws NullPointerException, PropertyNotFoundException, ELException {
156            if (context == null) {
157                throw new NullPointerException();
158            }
159    
160            if (base == null && property != null) {
161                int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString());
162                if (idx >= 0) {
163                    context.setPropertyResolved(true);
164                    return true;
165                }
166            }
167            return false;
168        }
169    
170        public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
171            List<FeatureDescriptor> feats = new ArrayList<FeatureDescriptor>(
172                    SCOPE_NAMES.length);
173            FeatureDescriptor feat;
174            for (int i = 0; i < SCOPE_NAMES.length; i++) {
175                feat = new FeatureDescriptor();
176                feat.setDisplayName(SCOPE_NAMES[i]);
177                feat.setExpert(false);
178                feat.setHidden(false);
179                feat.setName(SCOPE_NAMES[i]);
180                feat.setPreferred(true);
181                feat.setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
182                feat.setValue(TYPE, String.class);
183                feats.add(feat);
184            }
185            return feats.iterator();
186        }
187    
188        public Class<String> getCommonPropertyType(ELContext context, Object base) {
189            if (base == null) {
190                return String.class;
191            }
192            return null;
193        }
194    
195        private static class ScopeManager {
196            private final static String MNGR_KEY = ScopeManager.class.getName();
197    
198            private final PageContext page;
199    
200            private Map applicationScope;
201    
202            private Map cookie;
203    
204            private Map header;
205    
206            private Map headerValues;
207    
208            private Map initParam;
209    
210            private Map pageScope;
211    
212            private Map param;
213    
214            private Map paramValues;
215    
216            private Map requestScope;
217    
218            private Map sessionScope;
219    
220            public ScopeManager(PageContext page) {
221                this.page = page;
222            }
223    
224            public static ScopeManager get(PageContext page) {
225                ScopeManager mngr = (ScopeManager) page.getAttribute(MNGR_KEY);
226                if (mngr == null) {
227                    mngr = new ScopeManager(page);
228                    page.setAttribute(MNGR_KEY, mngr);
229                }
230                return mngr;
231            }
232    
233            public Map getApplicationScope() {
234                if (this.applicationScope == null) {
235                    this.applicationScope = new ScopeMap() {
236                        protected void setAttribute(String name, Object value) {
237                            page.getServletContext().setAttribute(name, value);
238                        }
239    
240                        protected void removeAttribute(String name) {
241                            page.getServletContext().removeAttribute(name);
242                        }
243    
244                        protected Enumeration getAttributeNames() {
245                            return page.getServletContext().getAttributeNames();
246                        }
247    
248                        protected Object getAttribute(String name) {
249                            return page.getServletContext().getAttribute(name);
250                        }
251                    };
252                }
253                return this.applicationScope;
254            }
255    
256            public Map getCookie() {
257                if (this.cookie == null) {
258                    this.cookie = new ScopeMap() {
259                        protected Enumeration getAttributeNames() {
260                            Cookie[] c = ((HttpServletRequest) page.getRequest())
261                                    .getCookies();
262                            if (c != null) {
263                                Vector v = new Vector();
264                                for (int i = 0; i < c.length; i++) {
265                                    v.add(c[i].getName());
266                                }
267                                return v.elements();
268                            }
269                            return null;
270                        }
271    
272                        protected Object getAttribute(String name) {
273                            Cookie[] c = ((HttpServletRequest) page.getRequest())
274                                    .getCookies();
275                            if (c != null) {
276                                for (int i = 0; i < c.length; i++) {
277                                    if (name.equals(c[i].getName())) {
278                                        return c[i];
279                                    }
280                                }
281                            }
282                            return null;
283                        }
284    
285                    };
286                }
287                return this.cookie;
288            }
289    
290            public Map getHeader() {
291                if (this.header == null) {
292                    this.header = new ScopeMap() {
293                        protected Enumeration getAttributeNames() {
294                            return ((HttpServletRequest) page.getRequest())
295                                    .getHeaderNames();
296                        }
297    
298                        protected Object getAttribute(String name) {
299                            return ((HttpServletRequest) page.getRequest())
300                                    .getHeader(name);
301                        }
302                    };
303                }
304                return this.header;
305            }
306    
307            public Map getHeaderValues() {
308                if (this.headerValues == null) {
309                    this.headerValues = new ScopeMap() {
310                        protected Enumeration getAttributeNames() {
311                            return ((HttpServletRequest) page.getRequest())
312                                    .getHeaderNames();
313                        }
314    
315                        protected Object getAttribute(String name) {
316                            Enumeration e = ((HttpServletRequest) page.getRequest())
317                                    .getHeaders(name);
318                            if (e != null) {
319                                List list = new ArrayList();
320                                while (e.hasMoreElements()) {
321                                    list.add(e.nextElement().toString());
322                                }
323                                return (String[]) list.toArray(new String[list
324                                        .size()]);
325                            }
326                            return null;
327                        }
328    
329                    };
330                }
331                return this.headerValues;
332            }
333    
334            public Map getInitParam() {
335                if (this.initParam == null) {
336                    this.initParam = new ScopeMap() {
337                        protected Enumeration getAttributeNames() {
338                            return page.getServletContext().getInitParameterNames();
339                        }
340    
341                        protected Object getAttribute(String name) {
342                            return page.getServletContext().getInitParameter(name);
343                        }
344                    };
345                }
346                return this.initParam;
347            }
348    
349            public PageContext getPageContext() {
350                return this.page;
351            }
352    
353            public Map getPageScope() {
354                if (this.pageScope == null) {
355                    this.pageScope = new ScopeMap() {
356                        protected void setAttribute(String name, Object value) {
357                            page.setAttribute(name, value);
358                        }
359    
360                        protected void removeAttribute(String name) {
361                            page.removeAttribute(name);
362                        }
363    
364                        protected Enumeration getAttributeNames() {
365                            return page
366                                    .getAttributeNamesInScope(PageContext.PAGE_SCOPE);
367                        }
368    
369                        protected Object getAttribute(String name) {
370                            return page.getAttribute(name);
371                        }
372                    };
373                }
374                return this.pageScope;
375            }
376    
377            public Map getParam() {
378                if (this.param == null) {
379                    this.param = new ScopeMap() {
380                        protected Enumeration getAttributeNames() {
381                            return page.getRequest().getParameterNames();
382                        }
383    
384                        protected Object getAttribute(String name) {
385                            return page.getRequest().getParameter(name);
386                        }
387                    };
388                }
389                return this.param;
390            }
391    
392            public Map getParamValues() {
393                if (this.paramValues == null) {
394                    this.paramValues = new ScopeMap() {
395                        protected Object getAttribute(String name) {
396                            return page.getRequest().getParameterValues(name);
397                        }
398    
399                        protected Enumeration getAttributeNames() {
400                            return page.getRequest().getParameterNames();
401                        }
402                    };
403                }
404                return this.paramValues;
405            }
406    
407            public Map getRequestScope() {
408                if (this.requestScope == null) {
409                    this.requestScope = new ScopeMap() {
410                        protected void setAttribute(String name, Object value) {
411                            page.getRequest().setAttribute(name, value);
412                        }
413    
414                        protected void removeAttribute(String name) {
415                            page.getRequest().removeAttribute(name);
416                        }
417    
418                        protected Enumeration getAttributeNames() {
419                            return page.getRequest().getAttributeNames();
420                        }
421    
422                        protected Object getAttribute(String name) {
423                            return page.getRequest().getAttribute(name);
424                        }
425                    };
426                }
427                return this.requestScope;
428            }
429    
430            public Map getSessionScope() {
431                if (this.sessionScope == null) {
432                    this.sessionScope = new ScopeMap() {
433                        protected void setAttribute(String name, Object value) {
434                            ((HttpServletRequest) page.getRequest()).getSession()
435                                    .setAttribute(name, value);
436                        }
437    
438                        protected void removeAttribute(String name) {
439                            HttpSession session = page.getSession();
440                            if (session != null) {
441                                session.removeAttribute(name);
442                            }
443                        }
444    
445                        protected Enumeration getAttributeNames() {
446                            HttpSession session = page.getSession();
447                            if (session != null) {
448                                return session.getAttributeNames();
449                            }
450                            return null;
451                        }
452    
453                        protected Object getAttribute(String name) {
454                            HttpSession session = page.getSession();
455                            if (session != null) {
456                                return session.getAttribute(name);
457                            }
458                            return null;
459                        }
460                    };
461                }
462                return this.sessionScope;
463            }
464        }
465    
466        private abstract static class ScopeMap extends AbstractMap {
467    
468            protected abstract Enumeration getAttributeNames();
469    
470            protected abstract Object getAttribute(String name);
471    
472            protected void removeAttribute(String name) {
473                throw new UnsupportedOperationException();
474            }
475    
476            protected void setAttribute(String name, Object value) {
477                throw new UnsupportedOperationException();
478            }
479    
480            public final Set entrySet() {
481                Enumeration e = getAttributeNames();
482                Set set = new HashSet();
483                if (e != null) {
484                    while (e.hasMoreElements()) {
485                        set.add(new ScopeEntry((String) e.nextElement()));
486                    }
487                }
488                return set;
489            }
490    
491            private class ScopeEntry implements Map.Entry {
492    
493                private final String key;
494    
495                public ScopeEntry(String key) {
496                    this.key = key;
497                }
498    
499                public Object getKey() {
500                    return (Object) this.key;
501                }
502    
503                public Object getValue() {
504                    return getAttribute(this.key);
505                }
506    
507                public Object setValue(Object value) {
508                    if (value == null) {
509                        removeAttribute(this.key);
510                    } else {
511                        setAttribute(this.key, value);
512                    }
513                    return null;
514                }
515    
516                public boolean equals(Object obj) {
517                    return (obj != null && this.hashCode() == obj.hashCode());
518                }
519    
520                public int hashCode() {
521                    return this.key.hashCode();
522                }
523    
524            }
525    
526            public final Object get(Object key) {
527                if (key != null) {
528                    return getAttribute(key.toString());
529                }
530                return null;
531            }
532    
533            public final Object put(Object key, Object value) {
534                if (key == null) {
535                    throw new NullPointerException();
536                }
537                if (value == null) {
538                    this.removeAttribute(key.toString());
539                } else {
540                    this.setAttribute(key.toString(), value);
541                }
542                return null;
543            }
544    
545            public final Object remove(Object key) {
546                if (key == null) {
547                    throw new NullPointerException();
548                }
549                this.removeAttribute(key.toString());
550                return null;
551            }
552    
553        }
554    
555    }