001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.jasper;
018:
019: import java.io.File;
020: import java.util.*;
021:
022: import javax.servlet.ServletConfig;
023: import javax.servlet.ServletContext;
024:
025: import org.apache.jasper.compiler.TldLocationsCache;
026: import org.apache.jasper.compiler.JspConfig;
027: import org.apache.jasper.compiler.TagPluginManager;
028: import org.apache.jasper.compiler.Localizer;
029: import org.apache.jasper.xmlparser.ParserUtils;
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032:
033: /**
034: * A class to hold all init parameters specific to the JSP engine.
035: *
036: * @author Anil K. Vijendran
037: * @author Hans Bergsten
038: * @author Pierre Delisle
039: */
040: public final class EmbeddedServletOptions implements Options {
041:
042: // Logger
043: private static Log log = LogFactory
044: .getLog(EmbeddedServletOptions.class);
045:
046: private Properties settings = new Properties();
047:
048: /**
049: * Is Jasper being used in development mode?
050: */
051: private boolean development = true;
052:
053: /**
054: * Should Ant fork its java compiles of JSP pages.
055: */
056: public boolean fork = true;
057:
058: /**
059: * Do you want to keep the generated Java files around?
060: */
061: private boolean keepGenerated = true;
062:
063: /**
064: * Should white spaces between directives or actions be trimmed?
065: */
066: private boolean trimSpaces = false;
067:
068: /**
069: * Determines whether tag handler pooling is enabled.
070: */
071: private boolean isPoolingEnabled = true;
072:
073: /**
074: * Do you want support for "mapped" files? This will generate
075: * servlet that has a print statement per line of the JSP file.
076: * This seems like a really nice feature to have for debugging.
077: */
078: private boolean mappedFile = true;
079:
080: /**
081: * Do you want stack traces and such displayed in the client's
082: * browser? If this is false, such messages go to the standard
083: * error or a log file if the standard error is redirected.
084: */
085: private boolean sendErrorToClient = false;
086:
087: /**
088: * Do we want to include debugging information in the class file?
089: */
090: private boolean classDebugInfo = true;
091:
092: /**
093: * Background compile thread check interval in seconds.
094: */
095: private int checkInterval = 300;
096:
097: /**
098: * JSP reloading check ?
099: */
100: private boolean reloading = true;
101:
102: /**
103: * Is the generation of SMAP info for JSR45 debuggin suppressed?
104: */
105: private boolean isSmapSuppressed = false;
106:
107: /**
108: * Should SMAP info for JSR45 debugging be dumped to a file?
109: */
110: private boolean isSmapDumped = false;
111:
112: /**
113: * Are Text strings to be generated as char arrays?
114: */
115: private boolean genStringAsCharArray = false;
116:
117: private boolean errorOnUseBeanInvalidClassAttribute = true;
118:
119: /**
120: * I want to see my generated servlets. Which directory are they
121: * in?
122: */
123: private File scratchDir;
124:
125: /**
126: * Need to have this as is for versions 4 and 5 of IE. Can be set from
127: * the initParams so if it changes in the future all that is needed is
128: * to have a jsp initParam of type ieClassId="<value>"
129: */
130: private String ieClassId = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
131:
132: /**
133: * What classpath should I use while compiling generated servlets?
134: */
135: private String classpath = null;
136:
137: /**
138: * Compiler to use.
139: */
140: private String compiler = null;
141:
142: /**
143: * Cache for the TLD locations
144: */
145: private TldLocationsCache tldLocationsCache = null;
146:
147: /**
148: * Jsp config information
149: */
150: private JspConfig jspConfig = null;
151:
152: /**
153: * TagPluginManager
154: */
155: private TagPluginManager tagPluginManager = null;
156:
157: /**
158: * Java platform encoding to generate the JSP
159: * page servlet.
160: */
161: private String javaEncoding = "UTF8";
162:
163: /*
164: * Is generation of X-Powered-By response header enabled/disabled?
165: */
166: private boolean xpoweredBy;
167:
168: public String getProperty(String name) {
169: return settings.getProperty(name);
170: }
171:
172: public void setProperty(String name, String value) {
173: if (name != null && value != null) {
174: settings.setProperty(name, value);
175: }
176: }
177:
178: /**
179: * Are we keeping generated code around?
180: */
181: public boolean getKeepGenerated() {
182: return keepGenerated;
183: }
184:
185: /**
186: * Should white spaces between directives or actions be trimmed?
187: */
188: public boolean getTrimSpaces() {
189: return trimSpaces;
190: }
191:
192: public boolean isPoolingEnabled() {
193: return isPoolingEnabled;
194: }
195:
196: /**
197: * Are we supporting HTML mapped servlets?
198: */
199: public boolean getMappedFile() {
200: return mappedFile;
201: }
202:
203: /**
204: * Should errors be sent to client or thrown into stderr?
205: */
206: public boolean getSendErrorToClient() {
207: return sendErrorToClient;
208: }
209:
210: /**
211: * Should class files be compiled with debug information?
212: */
213: public boolean getClassDebugInfo() {
214: return classDebugInfo;
215: }
216:
217: /**
218: * Background JSP compile thread check intervall
219: */
220: public int getCheckInterval() {
221: return checkInterval;
222: }
223:
224: /**
225: * Is Jasper being used in development mode?
226: */
227: public boolean getDevelopment() {
228: return development;
229: }
230:
231: /**
232: * JSP reloading check ?
233: */
234: public boolean getReloading() {
235: return reloading;
236: }
237:
238: /**
239: * Is the generation of SMAP info for JSR45 debuggin suppressed?
240: */
241: public boolean isSmapSuppressed() {
242: return isSmapSuppressed;
243: }
244:
245: /**
246: * Should SMAP info for JSR45 debugging be dumped to a file?
247: */
248: public boolean isSmapDumped() {
249: return isSmapDumped;
250: }
251:
252: /**
253: * Are Text strings to be generated as char arrays?
254: */
255: public boolean genStringAsCharArray() {
256: return this .genStringAsCharArray;
257: }
258:
259: /**
260: * Class ID for use in the plugin tag when the browser is IE.
261: */
262: public String getIeClassId() {
263: return ieClassId;
264: }
265:
266: /**
267: * What is my scratch dir?
268: */
269: public File getScratchDir() {
270: return scratchDir;
271: }
272:
273: /**
274: * What classpath should I use while compiling the servlets
275: * generated from JSP files?
276: */
277: public String getClassPath() {
278: return classpath;
279: }
280:
281: /**
282: * Is generation of X-Powered-By response header enabled/disabled?
283: */
284: public boolean isXpoweredBy() {
285: return xpoweredBy;
286: }
287:
288: /**
289: * Compiler to use.
290: */
291: public String getCompiler() {
292: return compiler;
293: }
294:
295: public boolean getErrorOnUseBeanInvalidClassAttribute() {
296: return errorOnUseBeanInvalidClassAttribute;
297: }
298:
299: public void setErrorOnUseBeanInvalidClassAttribute(boolean b) {
300: errorOnUseBeanInvalidClassAttribute = b;
301: }
302:
303: public TldLocationsCache getTldLocationsCache() {
304: return tldLocationsCache;
305: }
306:
307: public void setTldLocationsCache(TldLocationsCache tldC) {
308: tldLocationsCache = tldC;
309: }
310:
311: public String getJavaEncoding() {
312: return javaEncoding;
313: }
314:
315: public boolean getFork() {
316: return fork;
317: }
318:
319: public JspConfig getJspConfig() {
320: return jspConfig;
321: }
322:
323: public TagPluginManager getTagPluginManager() {
324: return tagPluginManager;
325: }
326:
327: /**
328: * Create an EmbeddedServletOptions object using data available from
329: * ServletConfig and ServletContext.
330: */
331: public EmbeddedServletOptions(ServletConfig config,
332: ServletContext context) {
333:
334: Enumeration enum=config.getInitParameterNames();
335: while( enum.hasMoreElements() ) {
336: String k=(String)enum.nextElement();
337: String v=config.getInitParameter( k );
338: setProperty( k, v);
339: }
340:
341: // quick hack
342: String validating=config.getInitParameter( "validating");
343: if( "false".equals( validating )) ParserUtils.validating=false;
344:
345: String keepgen = config.getInitParameter("keepgenerated");
346: if (keepgen != null) {
347: if (keepgen.equalsIgnoreCase("true")) {
348: this .keepGenerated = true;
349: } else if (keepgen.equalsIgnoreCase("false")) {
350: this .keepGenerated = false;
351: } else {
352: if (log.isWarnEnabled()) {
353: log.warn(Localizer.getMessage("jsp.warning.keepgen"));
354: }
355: }
356: }
357:
358:
359: String trimsp = config.getInitParameter("trimSpaces");
360: if (trimsp != null) {
361: if (trimsp.equalsIgnoreCase("true")) {
362: trimSpaces = true;
363: } else if (trimsp.equalsIgnoreCase("false")) {
364: trimSpaces = false;
365: } else {
366: if (log.isWarnEnabled()) {
367: log.warn(Localizer.getMessage("jsp.warning.trimspaces"));
368: }
369: }
370: }
371:
372: this .isPoolingEnabled = true;
373: String poolingEnabledParam
374: = config.getInitParameter("enablePooling");
375: if (poolingEnabledParam != null
376: && !poolingEnabledParam.equalsIgnoreCase("true")) {
377: if (poolingEnabledParam.equalsIgnoreCase("false")) {
378: this .isPoolingEnabled = false;
379: } else {
380: if (log.isWarnEnabled()) {
381: log.warn(Localizer.getMessage("jsp.warning.enablePooling"));
382: }
383: }
384: }
385:
386: String mapFile = config.getInitParameter("mappedfile");
387: if (mapFile != null) {
388: if (mapFile.equalsIgnoreCase("true")) {
389: this .mappedFile = true;
390: } else if (mapFile.equalsIgnoreCase("false")) {
391: this .mappedFile = false;
392: } else {
393: if (log.isWarnEnabled()) {
394: log.warn(Localizer.getMessage("jsp.warning.mappedFile"));
395: }
396: }
397: }
398:
399: String senderr = config.getInitParameter("sendErrToClient");
400: if (senderr != null) {
401: if (senderr.equalsIgnoreCase("true")) {
402: this .sendErrorToClient = true;
403: } else if (senderr.equalsIgnoreCase("false")) {
404: this .sendErrorToClient = false;
405: } else {
406: if (log.isWarnEnabled()) {
407: log.warn(Localizer.getMessage("jsp.warning.sendErrToClient"));
408: }
409: }
410: }
411:
412: String debugInfo = config.getInitParameter("classdebuginfo");
413: if (debugInfo != null) {
414: if (debugInfo.equalsIgnoreCase("true")) {
415: this .classDebugInfo = true;
416: } else if (debugInfo.equalsIgnoreCase("false")) {
417: this .classDebugInfo = false;
418: } else {
419: if (log.isWarnEnabled()) {
420: log.warn(Localizer.getMessage("jsp.warning.classDebugInfo"));
421: }
422: }
423: }
424:
425: String checkInterval = config.getInitParameter("checkInterval");
426: if (checkInterval != null) {
427: try {
428: this .checkInterval = Integer.parseInt(checkInterval);
429: if (this .checkInterval == 0) {
430: this .checkInterval = 300;
431: if (log.isWarnEnabled()) {
432: log.warn(Localizer.getMessage("jsp.warning.checkInterval"));
433: }
434: }
435: } catch(NumberFormatException ex) {
436: if (log.isWarnEnabled()) {
437: log.warn(Localizer.getMessage("jsp.warning.checkInterval"));
438: }
439: }
440: }
441:
442: String development = config.getInitParameter("development");
443: if (development != null) {
444: if (development.equalsIgnoreCase("true")) {
445: this .development = true;
446: } else if (development.equalsIgnoreCase("false")) {
447: this .development = false;
448: } else {
449: if (log.isWarnEnabled()) {
450: log.warn(Localizer.getMessage("jsp.warning.development"));
451: }
452: }
453: }
454:
455: String reloading = config.getInitParameter("reloading");
456: if (reloading != null) {
457: if (reloading.equalsIgnoreCase("true")) {
458: this .reloading = true;
459: } else if (reloading.equalsIgnoreCase("false")) {
460: this .reloading = false;
461: } else {
462: if (log.isWarnEnabled()) {
463: log.warn(Localizer.getMessage("jsp.warning.reloading"));
464: }
465: }
466: }
467:
468: String suppressSmap = config.getInitParameter("suppressSmap");
469: if (suppressSmap != null) {
470: if (suppressSmap.equalsIgnoreCase("true")) {
471: isSmapSuppressed = true;
472: } else if (suppressSmap.equalsIgnoreCase("false")) {
473: isSmapSuppressed = false;
474: } else {
475: if (log.isWarnEnabled()) {
476: log.warn(Localizer.getMessage("jsp.warning.suppressSmap"));
477: }
478: }
479: }
480:
481: String dumpSmap = config.getInitParameter("dumpSmap");
482: if (dumpSmap != null) {
483: if (dumpSmap.equalsIgnoreCase("true")) {
484: isSmapDumped = true;
485: } else if (dumpSmap.equalsIgnoreCase("false")) {
486: isSmapDumped = false;
487: } else {
488: if (log.isWarnEnabled()) {
489: log.warn(Localizer.getMessage("jsp.warning.dumpSmap"));
490: }
491: }
492: }
493:
494: String genCharArray = config.getInitParameter("genStrAsCharArray");
495: if (genCharArray != null) {
496: if (genCharArray.equalsIgnoreCase("true")) {
497: genStringAsCharArray = true;
498: } else if (genCharArray.equalsIgnoreCase("false")) {
499: genStringAsCharArray = false;
500: } else {
501: if (log.isWarnEnabled()) {
502: log.warn(Localizer.getMessage("jsp.warning.genchararray"));
503: }
504: }
505: }
506:
507: String errBeanClass =
508: config.getInitParameter("errorOnUseBeanInvalidClassAttribute");
509: if (errBeanClass != null) {
510: if (errBeanClass.equalsIgnoreCase("true")) {
511: errorOnUseBeanInvalidClassAttribute = true;
512: } else if (errBeanClass.equalsIgnoreCase("false")) {
513: errorOnUseBeanInvalidClassAttribute = false;
514: } else {
515: if (log.isWarnEnabled()) {
516: log.warn(Localizer.getMessage("jsp.warning.errBean"));
517: }
518: }
519: }
520:
521: String ieClassId = config.getInitParameter("ieClassId");
522: if (ieClassId != null)
523: this .ieClassId = ieClassId;
524:
525: String classpath = config.getInitParameter("classpath");
526: if (classpath != null)
527: this .classpath = classpath;
528:
529: /*
530: * scratchdir
531: */
532: String dir = config.getInitParameter("scratchdir");
533: if (dir != null) {
534: scratchDir = new File(dir);
535: } else {
536: // First try the Servlet 2.2 javax.servlet.context.tempdir property
537: scratchDir = (File) context.getAttribute(Constants.TMP_DIR);
538: if (scratchDir == null) {
539: // Not running in a Servlet 2.2 container.
540: // Try to get the JDK 1.2 java.io.tmpdir property
541: dir = System.getProperty("java.io.tmpdir");
542: if (dir != null)
543: scratchDir = new File(dir);
544: }
545: }
546: if (this .scratchDir == null) {
547: log.fatal(Localizer.getMessage("jsp.error.no.scratch.dir"));
548: return;
549: }
550:
551: if (!(scratchDir.exists() && scratchDir.canRead() &&
552: scratchDir.canWrite() && scratchDir.isDirectory()))
553: log.fatal(Localizer.getMessage("jsp.error.bad.scratch.dir",
554: scratchDir.getAbsolutePath()));
555:
556: this .compiler = config.getInitParameter("compiler");
557:
558: String javaEncoding = config.getInitParameter("javaEncoding");
559: if (javaEncoding != null) {
560: this .javaEncoding = javaEncoding;
561: }
562:
563: String fork = config.getInitParameter("fork");
564: if (fork != null) {
565: if (fork.equalsIgnoreCase("true")) {
566: this .fork = true;
567: } else if (fork.equalsIgnoreCase("false")) {
568: this .fork = false;
569: } else {
570: if (log.isWarnEnabled()) {
571: log.warn(Localizer.getMessage("jsp.warning.fork"));
572: }
573: }
574: }
575:
576: /*
577: * X-Powered-By
578: */
579: String xpoweredBy = config.getInitParameter("xpoweredBy");
580: if (xpoweredBy != null) {
581: if (xpoweredBy.equalsIgnoreCase("true")) {
582: this .xpoweredBy = true;
583: } else if (xpoweredBy.equalsIgnoreCase("false")) {
584: this .xpoweredBy = false;
585: } else {
586: if (log.isWarnEnabled()) {
587: log.warn(Localizer.getMessage("jsp.warning.xpoweredBy"));
588: }
589: }
590: }
591:
592: // Setup the global Tag Libraries location cache for this
593: // web-application.
594: tldLocationsCache = new TldLocationsCache(context);
595:
596: // Setup the jsp config info for this web app.
597: jspConfig = new JspConfig(context);
598:
599: // Create a Tag plugin instance
600: tagPluginManager = new TagPluginManager(context);
601: }
602: }
|