View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.struts2.jasper.compiler;
18  
19  import org.apache.struts2.jasper.Constants;
20  import org.apache.struts2.jasper.JasperException;
21  
22  import javax.servlet.jsp.tagext.TagLibraryInfo;
23  import java.util.*;
24  
25  /***
26   * A repository for various info about the translation unit under compilation.
27   *
28   * @author Kin-man Chung
29   */
30  
31  class PageInfo {
32  
33      private Vector imports;
34      private Vector dependants;
35  
36      private BeanRepository beanRepository;
37      private HashMap taglibsMap;
38      private HashMap jspPrefixMapper;
39      private HashMap xmlPrefixMapper;
40      private HashMap nonCustomTagPrefixMap;
41      private String jspFile;
42      private String defaultLanguage = "java";
43      private String language;
44      private String defaultExtends = Constants.JSP_SERVLET_BASE;
45      private String xtends;
46      private String contentType = null;
47      private String session;
48      private boolean isSession = true;
49      private String bufferValue;
50      private int buffer = 8 * 1024;    // XXX confirm
51      private String autoFlush;
52      private boolean isAutoFlush = true;
53      private String isThreadSafeValue;
54      private boolean isThreadSafe = true;
55      private String isErrorPageValue;
56      private boolean isErrorPage = false;
57      private String errorPage = null;
58      private String info;
59  
60      private boolean scriptless = false;
61      private boolean scriptingInvalid = false;
62      private String isELIgnoredValue;
63      private boolean isELIgnored = false;
64      private String omitXmlDecl = null;
65      private String doctypeName = null;
66      private String doctypePublic = null;
67      private String doctypeSystem = null;
68  
69      private boolean isJspPrefixHijacked;
70  
71      // Set of all element and attribute prefixes used in this translation unit
72      private HashSet prefixes;
73  
74      private boolean hasJspRoot = false;
75      private Vector includePrelude;
76      private Vector includeCoda;
77      private Vector pluginDcls;      // Id's for tagplugin declarations
78  
79  
80      PageInfo(BeanRepository beanRepository, String jspFile) {
81  
82          this.jspFile = jspFile;
83          this.beanRepository = beanRepository;
84          this.taglibsMap = new HashMap();
85          this.jspPrefixMapper = new HashMap();
86          this.xmlPrefixMapper = new HashMap();
87          this.nonCustomTagPrefixMap = new HashMap();
88          this.imports = new Vector();
89          this.dependants = new Vector();
90          this.includePrelude = new Vector();
91          this.includeCoda = new Vector();
92          this.pluginDcls = new Vector();
93          this.prefixes = new HashSet();
94  
95          // Enter standard imports
96          for (int i = 0; i < Constants.STANDARD_IMPORTS.length; i++)
97              imports.add(Constants.STANDARD_IMPORTS[i]);
98      }
99  
100     /***
101      * Check if the plugin ID has been previously declared.  Make a not
102      * that this Id is now declared.
103      *
104      * @return true if Id has been declared.
105      */
106     public boolean isPluginDeclared(String id) {
107         if (pluginDcls.contains(id))
108             return true;
109         pluginDcls.add(id);
110         return false;
111     }
112 
113     public void addImports(List imports) {
114         this.imports.addAll(imports);
115     }
116 
117     public void addImport(String imp) {
118         this.imports.add(imp);
119     }
120 
121     public List getImports() {
122         return imports;
123     }
124 
125     public String getJspFile() {
126         return jspFile;
127     }
128 
129     public void addDependant(String d) {
130         if (!dependants.contains(d) && !jspFile.equals(d))
131             dependants.add(d);
132     }
133 
134     public List getDependants() {
135         return dependants;
136     }
137 
138     public BeanRepository getBeanRepository() {
139         return beanRepository;
140     }
141 
142     public void setScriptless(boolean s) {
143         scriptless = s;
144     }
145 
146     public boolean isScriptless() {
147         return scriptless;
148     }
149 
150     public void setScriptingInvalid(boolean s) {
151         scriptingInvalid = s;
152     }
153 
154     public boolean isScriptingInvalid() {
155         return scriptingInvalid;
156     }
157 
158     public List getIncludePrelude() {
159         return includePrelude;
160     }
161 
162     public void setIncludePrelude(Vector prelude) {
163         includePrelude = prelude;
164     }
165 
166     public List getIncludeCoda() {
167         return includeCoda;
168     }
169 
170     public void setIncludeCoda(Vector coda) {
171         includeCoda = coda;
172     }
173 
174     public void setHasJspRoot(boolean s) {
175         hasJspRoot = s;
176     }
177 
178     public boolean hasJspRoot() {
179         return hasJspRoot;
180     }
181 
182     public String getOmitXmlDecl() {
183         return omitXmlDecl;
184     }
185 
186     public void setOmitXmlDecl(String omit) {
187         omitXmlDecl = omit;
188     }
189 
190     public String getDoctypeName() {
191         return doctypeName;
192     }
193 
194     public void setDoctypeName(String doctypeName) {
195         this.doctypeName = doctypeName;
196     }
197 
198     public String getDoctypeSystem() {
199         return doctypeSystem;
200     }
201 
202     public void setDoctypeSystem(String doctypeSystem) {
203         this.doctypeSystem = doctypeSystem;
204     }
205 
206     public String getDoctypePublic() {
207         return doctypePublic;
208     }
209 
210     public void setDoctypePublic(String doctypePublic) {
211         this.doctypePublic = doctypePublic;
212     }
213 
214     /* Tag library and XML namespace management methods */
215 
216     public void setIsJspPrefixHijacked(boolean isHijacked) {
217         isJspPrefixHijacked = isHijacked;
218     }
219 
220     public boolean isJspPrefixHijacked() {
221         return isJspPrefixHijacked;
222     }
223 
224     /*
225      * Adds the given prefix to the set of prefixes of this translation unit.
226      *
227      * @param prefix The prefix to add
228      */
229     public void addPrefix(String prefix) {
230         prefixes.add(prefix);
231     }
232 
233     /*
234      * Checks to see if this translation unit contains the given prefix.
235      *
236      * @param prefix The prefix to check
237      *
238      * @return true if this translation unit contains the given prefix, false
239      * otherwise
240      */
241     public boolean containsPrefix(String prefix) {
242         return prefixes.contains(prefix);
243     }
244 
245     /*
246      * Maps the given URI to the given tag library.
247      *
248      * @param uri The URI to map
249      * @param info The tag library to be associated with the given URI
250      */
251     public void addTaglib(String uri, TagLibraryInfo info) {
252         taglibsMap.put(uri, info);
253     }
254 
255     /*
256      * Gets the tag library corresponding to the given URI.
257      *
258      * @return Tag library corresponding to the given URI
259      */
260     public TagLibraryInfo getTaglib(String uri) {
261         return (TagLibraryInfo) taglibsMap.get(uri);
262     }
263 
264     /*
265      * Gets the collection of tag libraries that are associated with a URI
266      *
267      * @return Collection of tag libraries that are associated with a URI
268      */
269     public Collection getTaglibs() {
270         return taglibsMap.values();
271     }
272 
273     /*
274      * Checks to see if the given URI is mapped to a tag library.
275      *
276      * @param uri The URI to map
277      *
278      * @return true if the given URI is mapped to a tag library, false
279      * otherwise
280      */
281     public boolean hasTaglib(String uri) {
282         return taglibsMap.containsKey(uri);
283     }
284 
285     /*
286      * Maps the given prefix to the given URI.
287      *
288      * @param prefix The prefix to map
289      * @param uri The URI to be associated with the given prefix
290      */
291     public void addPrefixMapping(String prefix, String uri) {
292         jspPrefixMapper.put(prefix, uri);
293     }
294 
295     /*
296      * Pushes the given URI onto the stack of URIs to which the given prefix
297      * is mapped.
298      *
299      * @param prefix The prefix whose stack of URIs is to be pushed
300      * @param uri The URI to be pushed onto the stack
301      */
302     public void pushPrefixMapping(String prefix, String uri) {
303         LinkedList stack = (LinkedList) xmlPrefixMapper.get(prefix);
304         if (stack == null) {
305             stack = new LinkedList();
306             xmlPrefixMapper.put(prefix, stack);
307         }
308         stack.addFirst(uri);
309     }
310 
311     /*
312      * Removes the URI at the top of the stack of URIs to which the given
313      * prefix is mapped.
314      *
315      * @param prefix The prefix whose stack of URIs is to be popped
316      */
317     public void popPrefixMapping(String prefix) {
318         LinkedList stack = (LinkedList) xmlPrefixMapper.get(prefix);
319         if (stack == null || stack.size() == 0) {
320             // XXX throw new Exception("XXX");
321         }
322         stack.removeFirst();
323     }
324 
325     /*
326      * Returns the URI to which the given prefix maps.
327      *
328      * @param prefix The prefix whose URI is sought
329      *
330      * @return The URI to which the given prefix maps
331      */
332     public String getURI(String prefix) {
333 
334         String uri = null;
335 
336         LinkedList stack = (LinkedList) xmlPrefixMapper.get(prefix);
337         if (stack == null || stack.size() == 0) {
338             uri = (String) jspPrefixMapper.get(prefix);
339         } else {
340             uri = (String) stack.getFirst();
341         }
342 
343         return uri;
344     }
345 
346 
347     /* Page/Tag directive attributes */
348 
349     /*
350      * language
351      */
352 
353     public void setLanguage(String value, Node n, ErrorDispatcher err,
354                             boolean pagedir)
355             throws JasperException {
356 
357         if (!"java".equalsIgnoreCase(value)) {
358             if (pagedir)
359                 err.jspError(n, "jsp.error.page.language.nonjava");
360             else
361                 err.jspError(n, "jsp.error.tag.language.nonjava");
362         }
363 
364         language = value;
365     }
366 
367     public String getLanguage(boolean useDefault) {
368         return (language == null && useDefault ? defaultLanguage : language);
369     }
370 
371     public String getLanguage() {
372         return getLanguage(true);
373     }
374 
375 
376     /*
377      * extends
378      */
379     public void setExtends(String value, Node.PageDirective n) {
380 
381         xtends = value;
382 
383         /*
384          * If page superclass is top level class (i.e. not in a package)
385          * explicitly import it. If this is not done, the compiler will assume
386          * the extended class is in the same pkg as the generated servlet.
387          */
388         if (value.indexOf('.') < 0)
389             n.addImport(value);
390     }
391 
392     /***
393      * Gets the value of the 'extends' page directive attribute.
394      *
395      * @param useDefault TRUE if the default
396      *                   (org.apache.jasper.runtime.HttpJspBase) should be returned if this
397      *                   attribute has not been set, FALSE otherwise
398      * @return The value of the 'extends' page directive attribute, or the
399      *         default (org.apache.jasper.runtime.HttpJspBase) if this attribute has
400      *         not been set and useDefault is TRUE
401      */
402     public String getExtends(boolean useDefault) {
403         return (xtends == null && useDefault ? defaultExtends : xtends);
404     }
405 
406     /***
407      * Gets the value of the 'extends' page directive attribute.
408      *
409      * @return The value of the 'extends' page directive attribute, or the
410      *         default (org.apache.jasper.runtime.HttpJspBase) if this attribute has
411      *         not been set
412      */
413     public String getExtends() {
414         return getExtends(true);
415     }
416 
417 
418     /*
419      * contentType
420      */
421     public void setContentType(String value) {
422         contentType = value;
423     }
424 
425     public String getContentType() {
426         return contentType;
427     }
428 
429 
430     /*
431      * buffer
432      */
433     public void setBufferValue(String value, Node n, ErrorDispatcher err)
434             throws JasperException {
435 
436         if ("none".equalsIgnoreCase(value))
437             buffer = 0;
438         else {
439             if (value == null || !value.endsWith("kb"))
440                 err.jspError(n, "jsp.error.page.invalid.buffer");
441             try {
442                 Integer k = new Integer(value.substring(0, value.length() - 2));
443                 buffer = k.intValue() * 1024;
444             } catch (NumberFormatException e) {
445                 err.jspError(n, "jsp.error.page.invalid.buffer");
446             }
447         }
448 
449         bufferValue = value;
450     }
451 
452     public String getBufferValue() {
453         return bufferValue;
454     }
455 
456     public int getBuffer() {
457         return buffer;
458     }
459 
460 
461     /*
462      * session
463      */
464     public void setSession(String value, Node n, ErrorDispatcher err)
465             throws JasperException {
466 
467         if ("true".equalsIgnoreCase(value))
468             isSession = true;
469         else if ("false".equalsIgnoreCase(value))
470             isSession = false;
471         else
472             err.jspError(n, "jsp.error.page.invalid.session");
473 
474         session = value;
475     }
476 
477     public String getSession() {
478         return session;
479     }
480 
481     public boolean isSession() {
482         return isSession;
483     }
484 
485 
486     /*
487      * autoFlush
488      */
489     public void setAutoFlush(String value, Node n, ErrorDispatcher err)
490             throws JasperException {
491 
492         if ("true".equalsIgnoreCase(value))
493             isAutoFlush = true;
494         else if ("false".equalsIgnoreCase(value))
495             isAutoFlush = false;
496         else
497             err.jspError(n, "jsp.error.autoFlush.invalid");
498 
499         autoFlush = value;
500     }
501 
502     public String getAutoFlush() {
503         return autoFlush;
504     }
505 
506     public boolean isAutoFlush() {
507         return isAutoFlush;
508     }
509 
510 
511     /*
512      * isThreadSafe
513      */
514     public void setIsThreadSafe(String value, Node n, ErrorDispatcher err)
515             throws JasperException {
516 
517         if ("true".equalsIgnoreCase(value))
518             isThreadSafe = true;
519         else if ("false".equalsIgnoreCase(value))
520             isThreadSafe = false;
521         else
522             err.jspError(n, "jsp.error.page.invalid.isthreadsafe");
523 
524         isThreadSafeValue = value;
525     }
526 
527     public String getIsThreadSafe() {
528         return isThreadSafeValue;
529     }
530 
531     public boolean isThreadSafe() {
532         return isThreadSafe;
533     }
534 
535 
536     /*
537      * info
538      */
539     public void setInfo(String value) {
540         info = value;
541     }
542 
543     public String getInfo() {
544         return info;
545     }
546 
547 
548     /*
549      * errorPage
550      */
551     public void setErrorPage(String value) {
552         errorPage = value;
553     }
554 
555     public String getErrorPage() {
556         return errorPage;
557     }
558 
559 
560     /*
561      * isErrorPage
562      */
563     public void setIsErrorPage(String value, Node n, ErrorDispatcher err)
564             throws JasperException {
565 
566         if ("true".equalsIgnoreCase(value))
567             isErrorPage = true;
568         else if ("false".equalsIgnoreCase(value))
569             isErrorPage = false;
570         else
571             err.jspError(n, "jsp.error.page.invalid.iserrorpage");
572 
573         isErrorPageValue = value;
574     }
575 
576     public String getIsErrorPage() {
577         return isErrorPageValue;
578     }
579 
580     public boolean isErrorPage() {
581         return isErrorPage;
582     }
583 
584 
585     /*
586      * isELIgnored
587      */
588     public void setIsELIgnored(String value, Node n, ErrorDispatcher err,
589                                boolean pagedir)
590             throws JasperException {
591 
592         if ("true".equalsIgnoreCase(value))
593             isELIgnored = true;
594         else if ("false".equalsIgnoreCase(value))
595             isELIgnored = false;
596         else {
597             if (pagedir)
598                 err.jspError(n, "jsp.error.page.invalid.iselignored");
599             else
600                 err.jspError(n, "jsp.error.tag.invalid.iselignored");
601         }
602 
603         isELIgnoredValue = value;
604     }
605 
606     public void setELIgnored(boolean s) {
607         isELIgnored = s;
608     }
609 
610     public String getIsELIgnored() {
611         return isELIgnoredValue;
612     }
613 
614     public boolean isELIgnored() {
615         return isELIgnored;
616     }
617 
618     public void putNonCustomTagPrefix(String prefix, Mark where) {
619         nonCustomTagPrefixMap.put(prefix, where);
620     }
621 
622     public Mark getNonCustomTagPrefix(String prefix) {
623         return (Mark) nonCustomTagPrefixMap.get(prefix);
624     }
625 }