001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jsp;
031:
032: import com.caucho.java.LineMap;
033: import com.caucho.jsp.cfg.JspPropertyGroup;
034: import com.caucho.log.Log;
035: import com.caucho.server.webapp.Application;
036: import com.caucho.util.CharBuffer;
037: import com.caucho.util.CharScanner;
038: import com.caucho.util.L10N;
039: import com.caucho.util.StringCharCursor;
040: import com.caucho.vfs.Depend;
041: import com.caucho.vfs.PersistentDependency;
042: import com.caucho.vfs.Path;
043: import com.caucho.xml.QName;
044:
045: import java.util.ArrayList;
046: import java.util.logging.Logger;
047:
048: /**
049: * Represents the current state of the parser.
050: */
051: public class ParseState {
052: private static final L10N L = new L10N(ParseState.class);
053: static final Logger log = Log.open(ParseState.class);
054:
055: private Application _application;
056:
057: private JspPropertyGroup _jspPropertyGroup = new JspPropertyGroup();
058:
059: private boolean _isELIgnored = false;
060: private boolean _isELIgnoredSet = false;
061: private boolean _isELIgnoredDefault = true;
062:
063: private boolean _isScriptingInvalid = false;
064:
065: private boolean _isVelocityEnabled;
066:
067: private boolean _isSession = true;
068: private boolean _isOptionalSession = false;
069: private boolean _isSessionSet = false;
070:
071: private boolean _isErrorPage = false;
072: private boolean _isErrorPageSet = false;
073:
074: private boolean _isAutoFlush = true;
075: private boolean _isAutoFlushSet = false;
076:
077: private boolean _isThreadSafe = true;
078: private boolean _isThreadSafeSet = false;
079:
080: private boolean _isTag = false;
081: private boolean _isXml = false;
082: private boolean _isForbidXml = false;
083:
084: private int _buffer = 8192;
085: private boolean _isBufferSet = false;
086:
087: private String _info;
088: private String _errorPage;
089: private String _contentType;
090: private String _charEncoding;
091: private String _pageEncoding;
092: private Class _extends;
093:
094: private boolean _recycleTags = true;
095: private boolean _isTrimWhitespace;
096: private boolean _isDeferredSyntaxAllowedAsLiteral;
097:
098: private JspResourceManager _resourceManager;
099:
100: private JspBuilder _jspBuilder;
101:
102: private ArrayList<String> _importList = new ArrayList<String>();
103:
104: private String _uriPwd;
105:
106: private ArrayList<PersistentDependency> _depends = new ArrayList<PersistentDependency>();
107: private LineMap _lineMap;
108:
109: private Namespace _namespaces;
110:
111: /**
112: * Create a new parse state instance.
113: */
114: public ParseState() {
115: }
116:
117: /**
118: * Sets the JSP property group.
119: */
120: public void setJspPropertyGroup(JspPropertyGroup group) {
121: _jspPropertyGroup = group;
122: }
123:
124: /**
125: * Gets the JSP property group.
126: */
127: public JspPropertyGroup getJspPropertyGroup() {
128: return _jspPropertyGroup;
129: }
130:
131: /**
132: * Returns true if JSP EL is ignored.
133: */
134: public boolean isELIgnored() {
135: return _isELIgnored;
136: }
137:
138: /**
139: * Set if JSP EL is ignored.
140: */
141: public boolean setELIgnored(boolean isELIgnored) {
142: boolean oldELIgnored = _isELIgnored;
143:
144: _isELIgnored = isELIgnored;
145: _isELIgnoredDefault = false;
146:
147: return (oldELIgnored == isELIgnored || !_isELIgnoredSet);
148: }
149:
150: /**
151: * Mark the el-ignored attribute as set.
152: */
153: public void markELIgnoredSet() {
154: _isELIgnoredSet = true;
155: }
156:
157: /**
158: * Set if JSP EL is ignored.
159: */
160: public void setELIgnoredDefault(boolean isELIgnored) {
161: if (_isELIgnoredDefault)
162: _isELIgnored = isELIgnored;
163: }
164:
165: /**
166: * Returns true if JSP scripting is invalidn.
167: */
168: public boolean isScriptingInvalid() {
169: return _isScriptingInvalid;
170: }
171:
172: /**
173: * Set if JSP scripting is ignored.
174: */
175: public void setScriptingInvalid(boolean isScriptingInvalid) {
176: _isScriptingInvalid = isScriptingInvalid;
177: }
178:
179: /**
180: * Set if velocity statements are enabled.
181: */
182: public void setVelocityEnabled(boolean isVelocity) {
183: _isVelocityEnabled = isVelocity;
184: }
185:
186: /**
187: * Returns true if Velocity statements are enabled.
188: */
189: public boolean isVelocityEnabled() {
190: return _isVelocityEnabled;
191: }
192:
193: /**
194: * Returns true if the session is enabled.
195: */
196: public boolean isSession() {
197: return _isSession;
198: }
199:
200: /**
201: * Returns true if the optional session is enabled.
202: */
203: public boolean isOptionalSession() {
204: return _isOptionalSession;
205: }
206:
207: /**
208: * Set if the session is enabled.
209: */
210: public boolean setSession(boolean session) {
211: boolean isSession = _isSession;
212:
213: _isSession = session;
214: _isOptionalSession = session;
215:
216: return (session == isSession || !_isSessionSet);
217: }
218:
219: /**
220: * Mark the thread safe attribute as set.
221: */
222: public void markSessionSet() {
223: _isSessionSet = true;
224: }
225:
226: /**
227: * Returns true if the autoFlush is enabled.
228: */
229: public boolean isAutoFlush() {
230: return _isAutoFlush;
231: }
232:
233: /**
234: * Set if the autoFlush is enabled.
235: */
236: public boolean setAutoFlush(boolean autoFlush) {
237: boolean isAutoFlush = _isAutoFlush;
238:
239: _isAutoFlush = autoFlush;
240:
241: return (autoFlush == isAutoFlush || !_isAutoFlushSet);
242: }
243:
244: /**
245: * Mark the thread safe attribute as set.
246: */
247: public void markAutoFlushSet() {
248: _isAutoFlushSet = true;
249: }
250:
251: /**
252: * Returns true if the threadSafe is enabled.
253: */
254: public boolean isThreadSafe() {
255: return _isThreadSafe;
256: }
257:
258: /**
259: * Set if the threadSafe is enabled.
260: */
261: public boolean setThreadSafe(boolean threadSafe) {
262: boolean isThreadSafe = _isThreadSafe;
263:
264: _isThreadSafe = threadSafe;
265:
266: return (threadSafe == isThreadSafe || !_isThreadSafeSet);
267: }
268:
269: /**
270: * Mark the thread safe attribute as set.
271: */
272: public void markThreadSafeSet() {
273: _isThreadSafeSet = true;
274: }
275:
276: /**
277: * Set if the errorPage is enabled.
278: */
279: public boolean setErrorPage(boolean errorPage) {
280: boolean isErrorPage = _isErrorPage;
281:
282: _isErrorPage = errorPage;
283:
284: return (errorPage == isErrorPage || !_isErrorPageSet);
285: }
286:
287: /**
288: * Returns true if the errorPage is enabled.
289: */
290: public boolean isErrorPage() {
291: return _isErrorPage;
292: }
293:
294: /**
295: * Mark the error page attribute as set.
296: */
297: public void markErrorPage() {
298: _isErrorPageSet = true;
299: }
300:
301: /**
302: * Returns the buffer size in bytes.
303: */
304: public int getBuffer() {
305: return _buffer;
306: }
307:
308: /**
309: * Set the buffer size.
310: */
311: public boolean setBuffer(int buffer) {
312: int oldBuffer = _buffer;
313:
314: _buffer = buffer;
315:
316: return (buffer == oldBuffer || !_isBufferSet);
317: }
318:
319: /**
320: * Mark the buffer attribute as set.
321: */
322: public void markBufferSet() {
323: _isBufferSet = true;
324: }
325:
326: /**
327: * Sets the JSP's error page
328: */
329: public void setErrorPage(String errorPage) {
330: _errorPage = errorPage;
331: }
332:
333: /**
334: * Gets the JSP's error page
335: */
336: public String getErrorPage() {
337: return _errorPage;
338: }
339:
340: /**
341: * Sets the JSP's content type
342: */
343: public void setContentType(String contentType) {
344: _contentType = contentType;
345: }
346:
347: /**
348: * Gets the JSP's content type
349: */
350: public String getContentType() {
351: return _contentType;
352: }
353:
354: /**
355: * Sets the JSP's character encoding
356: */
357: public void setCharEncoding(String charEncoding)
358: throws JspParseException {
359: /*
360: if (_charEncoding != null &&
361: ! _charEncoding.equalsIgnoreCase(charEncoding))
362: throw new JspParseException(L.l("Cannot change character encoding to '{0}' (old value '{1}'). The character encoding may only be set once.",
363: charEncoding, _charEncoding));
364: */
365:
366: _charEncoding = charEncoding;
367: }
368:
369: /**
370: * Gets the JSP's character encoding
371: */
372: public String getCharEncoding() {
373: return _charEncoding;
374: }
375:
376: /**
377: * Sets the JSP's page encoding
378: */
379: public void setPageEncoding(String pageEncoding)
380: throws JspParseException {
381: if (pageEncoding == null)
382: return;
383:
384: if (_pageEncoding == null
385: || _pageEncoding.equalsIgnoreCase(pageEncoding)) {
386: _pageEncoding = pageEncoding;
387: } else if ("UTF-16".equalsIgnoreCase(_pageEncoding)
388: && ("UTF-16LE".equalsIgnoreCase(pageEncoding) || "UTF-16BE"
389: .equalsIgnoreCase(pageEncoding))) {
390: _pageEncoding = pageEncoding;
391: } else if ("UTF-16".equalsIgnoreCase(pageEncoding)
392: && ("UTF-16LE".equalsIgnoreCase(_pageEncoding) || "UTF-16BE"
393: .equalsIgnoreCase(_pageEncoding))) {
394: } else {
395: String oldPageEncoding = _pageEncoding;
396:
397: _pageEncoding = pageEncoding;
398:
399: throw new JspParseException(
400: L
401: .l(
402: "Cannot change page encoding to '{0}' (old value '{1}'). The page encoding may only be set once.",
403: pageEncoding, oldPageEncoding));
404: }
405:
406: }
407:
408: /**
409: * Gets the JSP's character encoding
410: */
411: public String getPageEncoding() {
412: return _pageEncoding;
413: }
414:
415: /**
416: * Returns the JSP's info string.
417: */
418: public String getInfo() {
419: return _info;
420: }
421:
422: /**
423: * Sets the JSP's info string
424: */
425: public void setInfo(String info) {
426: _info = info;
427: }
428:
429: /**
430: * Returns the JSP's extends
431: */
432: public Class getExtends() {
433: return _extends;
434: }
435:
436: /**
437: * Sets the JSP's extends
438: */
439: public void setExtends(Class extendsValue) {
440: _extends = extendsValue;
441: }
442:
443: /**
444: * Returns true if parsing is a tag
445: */
446: public boolean isTag() {
447: return _isTag;
448: }
449:
450: /**
451: * Set if parsing a tag
452: */
453: public void setTag(boolean isTag) {
454: _isTag = isTag;
455: }
456:
457: /**
458: * Returns true if parsing is XML
459: */
460: public boolean isXml() {
461: return _isXml;
462: }
463:
464: /**
465: * Set if parsing is xml
466: */
467: public void setXml(boolean isXml) {
468: _isXml = isXml;
469: }
470:
471: /**
472: * Returns true if parsing forbids XML
473: */
474: public boolean isForbidXml() {
475: return _isForbidXml;
476: }
477:
478: /**
479: * Set if parsing forbids xml
480: */
481: public void setForbidXml(boolean isForbidXml) {
482: _isForbidXml = isForbidXml;
483: }
484:
485: /**
486: * Returns true if the print-null-as-blank is enabled.
487: */
488: public boolean isPrintNullAsBlank() {
489: return _jspPropertyGroup.isPrintNullAsBlank();
490: }
491:
492: /**
493: * Returns true if JSP whitespace is trimmed.
494: */
495: public boolean isTrimWhitespace() {
496: return _isTrimWhitespace;
497: }
498:
499: /**
500: * Set true if JSP whitespace is trimmed.
501: */
502: public void setTrimWhitespace(boolean trim) {
503: _isTrimWhitespace = trim;
504: }
505:
506: /**
507: * Returns true if JSP whitespace is trimmed.
508: */
509: public boolean isDeferredSyntaxAllowedAsLiteral() {
510: return _isDeferredSyntaxAllowedAsLiteral;
511: }
512:
513: /**
514: * Set true if JSP whitespace is trimmed.
515: */
516: public void setDeferredSyntaxAllowedAsLiteral(boolean trim) {
517: _isDeferredSyntaxAllowedAsLiteral = trim;
518: }
519:
520: /**
521: * Gets the resource manager.
522: */
523: public JspResourceManager getResourceManager() {
524: return _resourceManager;
525: }
526:
527: /**
528: * Sets the resource manager.
529: */
530: public void setResourceManager(JspResourceManager resourceManager) {
531: _resourceManager = resourceManager;
532: }
533:
534: /**
535: * Gets the builder
536: */
537: public JspBuilder getBuilder() {
538: return _jspBuilder;
539: }
540:
541: /**
542: * Sets the builder
543: */
544: public void setBuilder(JspBuilder jspBuilder) {
545: _jspBuilder = jspBuilder;
546: }
547:
548: private static CharScanner COMMA_DELIM_SCANNER = new CharScanner(
549: " \t\n\r,");
550:
551: /**
552: * Adds an import string.
553: */
554: public void addImport(String importString) throws JspParseException {
555: String[] imports = importString.split("[ \t\n\r,]+");
556:
557: for (int i = 0; i < imports.length; i++) {
558: String value = imports[i];
559:
560: if (value.equals(""))
561: continue;
562:
563: if (value.equals("static") && i + 1 < imports.length) {
564: value = "static " + imports[i + 1];
565: i++;
566: }
567:
568: if (!_importList.contains(value))
569: _importList.add(value);
570: }
571: }
572:
573: /**
574: * Returns the import list.
575: */
576: public ArrayList<String> getImportList() {
577: return _importList;
578: }
579:
580: /**
581: * Sets the URI pwd
582: */
583: public void setUriPwd(String uriPwd) {
584: _uriPwd = uriPwd;
585: }
586:
587: /**
588: * Gets the URI pwd
589: */
590: public String getUriPwd() {
591: return _uriPwd;
592: }
593:
594: /**
595: * Returns the line map.
596: */
597: public LineMap getLineMap() {
598: return _lineMap;
599: }
600:
601: /**
602: * Add a dependency.
603: */
604: public void addDepend(Path path) {
605: PersistentDependency depend = path.createDepend();
606: if (!_depends.contains(depend))
607: _depends.add(depend);
608: }
609:
610: /**
611: * Returns the dependencies
612: */
613: public ArrayList<PersistentDependency> getDependList() {
614: return _depends;
615: }
616:
617: /**
618: * Resolves a path.
619: *
620: * @param uri the uri for the path
621: *
622: * @return the Path
623: */
624: public Path resolvePath(String uri) {
625: return getResourceManager().resolvePath(uri);
626: }
627:
628: /**
629: * Set if recycle-tags is enabled.
630: */
631: public void setRecycleTags(boolean recycleTags) {
632: _recycleTags = recycleTags;
633: }
634:
635: /**
636: * Returns true if recycle-tags is enabled.
637: */
638: public boolean isRecycleTags() {
639: return _recycleTags;
640: }
641:
642: /**
643: * Returns the QName for the given name.
644: */
645: public QName getQName(String name) {
646: int p = name.indexOf(':');
647:
648: if (p < 0)
649: return new QName(name);
650: else {
651: String prefix = name.substring(0, p);
652: String uri = Namespace.find(_namespaces, prefix);
653:
654: if (uri != null)
655: return new QName(name, uri);
656: else
657: return new QName(name);
658: }
659: }
660:
661: public Namespace getNamespaces() {
662: return _namespaces;
663: }
664:
665: /**
666: * Pushes a namespace.
667: */
668: public void pushNamespace(String prefix, String uri) {
669: _namespaces = new Namespace(_namespaces, prefix, uri);
670: }
671:
672: /**
673: * Pops a namespace.
674: */
675: public void popNamespace(String prefix) {
676: if (_namespaces._prefix.equals(prefix))
677: _namespaces = _namespaces.getNext();
678: else
679: throw new IllegalStateException();
680: }
681:
682: public String findPrefix(String uri) {
683: return Namespace.findPrefix(_namespaces, uri);
684: }
685: }
|