001: package com.meterware.httpunit;
002:
003: /********************************************************************************************************************
004: * $Id: HttpUnitOptions.java,v 1.43 2004/09/29 17:15:24 russgold Exp $
005: *
006: * Copyright (c) 2000-2004, Russell Gold
007: *
008: * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
009: * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
010: * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
011: * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included in all copies or substantial portions
014: * of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
017: * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
019: * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
020: * DEALINGS IN THE SOFTWARE.
021: *
022: *******************************************************************************************************************/
023:
024: import com.meterware.httpunit.scripting.ScriptingEngineFactory;
025: import com.meterware.httpunit.parsing.HTMLParserListener;
026: import com.meterware.httpunit.parsing.HTMLParserFactory;
027:
028: import java.util.Vector;
029:
030: /**
031: * A collection of global options to control HttpUnit's behavior.
032: *
033: * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a>
034: * @author <a href="mailto:dglo@ssec.wisc.edu">Dave Glowacki</a>
035: * @author <a href="mailto:bx@bigfoot.com">Benoit Xhenseval</a>
036: **/
037: public abstract class HttpUnitOptions {
038:
039: final static public String DEFAULT_SCRIPT_ENGINE_FACTORY = "com.meterware.httpunit.javascript.JavaScriptEngineFactory";
040:
041: /**
042: * Resets all options to their default values.
043: */
044: public static void reset() {
045: _exceptionsOnErrorStatus = true;
046: _parameterValuesValidated = true;
047: _imagesTreatedAsAltText = false;
048: _loggingHttpHeaders = false;
049: _matchesIgnoreCase = true;
050: _checkContentLength = false;
051: _redirectDelay = 0; // TODO move this to ClientProperties
052: _characterSet = HttpUnitUtils.DEFAULT_CHARACTER_SET;
053: _contentType = DEFAULT_CONTENT_TYPE;
054: _postIncludesCharset = false;
055: _exceptionsThrownOnScriptError = true;
056: setScriptEngineClassName(DEFAULT_SCRIPT_ENGINE_FACTORY);
057: setScriptingEnabled(true);
058: }
059:
060: /**
061: * Returns true if HttpUnit is accepting and saving cookies. The default is to accept them.
062: * @deprecated as of 1.5.3, use ClientProperties#isAcceptCookies();
063: */
064: public static boolean isAcceptCookies() {
065: return ClientProperties.getDefaultProperties()
066: .isAcceptCookies();
067: }
068:
069: /**
070: * Specifies whether HttpUnit should accept and send cookies.
071: * @deprecated as of 1.5.3, use ClientProperties#setAcceptCookies();
072: */
073: public static void setAcceptCookies(boolean acceptCookies) {
074: ClientProperties.getDefaultProperties().setAcceptCookies(
075: acceptCookies);
076: }
077:
078: /**
079: * Returns true if any WebClient created will accept GZIP encoding of responses. The default is to accept GZIP encoding.
080: * @deprecated as of 1.5.3, use ClientProperties#isAcceptGzip();
081: **/
082: public static boolean isAcceptGzip() {
083: return ClientProperties.getDefaultProperties().isAcceptGzip();
084: }
085:
086: /**
087: * Specifies whether a WebClient will be initialized to accept GZIP encoded responses. The default is true.
088: * @deprecated as of 1.5.3, use ClientProperties#setAcceptGzip();
089: */
090: public static void setAcceptGzip(boolean acceptGzip) {
091: ClientProperties.getDefaultProperties().setAcceptGzip(
092: acceptGzip);
093: }
094:
095: /**
096: * Resets the default character set to the HTTP default encoding.
097: **/
098: public static void resetDefaultCharacterSet() {
099: _characterSet = HttpUnitUtils.DEFAULT_CHARACTER_SET;
100: }
101:
102: /**
103: * Resets the default content type to plain text.
104: **/
105: public static void resetDefaultContentType() {
106: _contentType = DEFAULT_CONTENT_TYPE;
107: }
108:
109: /**
110: * Sets the default character set for pages which do not specify one and for requests created without HTML sources.
111: * By default, HttpUnit uses the HTTP default encoding, iso-8859-1.
112: **/
113: public static void setDefaultCharacterSet(String characterSet) {
114: _characterSet = characterSet;
115: }
116:
117: /**
118: * Returns the character set to be used for pages which do not specify one.
119: **/
120: public static String getDefaultCharacterSet() {
121: return _characterSet;
122: }
123:
124: /**
125: * Returns true if HttpUnit will throw an exception when a message is only partially received. The default is
126: * to avoid such checks.
127: */
128: public static boolean isCheckContentLength() {
129: return _checkContentLength;
130: }
131:
132: /**
133: * Specifies whether HttpUnit should throw an exception when the content length of a message does not match its
134: * actual received length. Defaults to false.
135: */
136: public static void setCheckContentLength(boolean checkContentLength) {
137: _checkContentLength = checkContentLength;
138: }
139:
140: /**
141: * Determines whether a normal POST request will include the character set in the content-type header.
142: * The default is to include it; however, some older servlet engines (most notably Tomcat 3.1) get confused
143: * when they see it.
144: **/
145: public static void setPostIncludesCharset(
146: boolean postIncludesCharset) {
147: _postIncludesCharset = postIncludesCharset;
148: }
149:
150: /**
151: * Returns true if POST requests should include the character set in the content-type header.
152: **/
153: public static boolean isPostIncludesCharset() {
154: return _postIncludesCharset;
155: }
156:
157: /**
158: * Sets the default content type for pages which do not specify one.
159: **/
160: public static void setDefaultContentType(String contentType) {
161: _contentType = contentType;
162: }
163:
164: /**
165: * Returns the content type to be used for pages which do not specify one.
166: **/
167: public static String getDefaultContentType() {
168: return _contentType;
169: }
170:
171: /**
172: * Returns true if parser warnings are enabled.
173: * @deprecated as of 1.5.2, use HTMLParserFactory#isParserWarningsEnabled
174: **/
175: public static boolean getParserWarningsEnabled() {
176: return HTMLParserFactory.isParserWarningsEnabled();
177: }
178:
179: /**
180: * If true, tells the parser to display warning messages. The default is false (warnings are not shown).
181: * @deprecated as of 1.5.2, use HTMLParserFactory#setParserWarningsEnabled
182: **/
183: public static void setParserWarningsEnabled(boolean enabled) {
184: HTMLParserFactory.setParserWarningsEnabled(enabled);
185: }
186:
187: /**
188: * If true, WebClient.getResponse throws an exception when it receives an error status.
189: * Defaults to true.
190: **/
191: public static void setExceptionsThrownOnErrorStatus(boolean enabled) {
192: _exceptionsOnErrorStatus = enabled;
193: }
194:
195: /**
196: * Returns true if WebClient.getResponse throws exceptions when detected an error status.
197: **/
198: public static boolean getExceptionsThrownOnErrorStatus() {
199: return _exceptionsOnErrorStatus;
200: }
201:
202: /**
203: * Returns true if form parameter settings are checked.
204: *
205: * @deprecated as of 1.6, use WebForm#newUnvalidatedRequest() to obtain a request without parameter validation.
206: **/
207: public static boolean getParameterValuesValidated() {
208: return _parameterValuesValidated;
209: }
210:
211: /**
212: * If true, tells HttpUnit to throw an exception on any attempt to set a form parameter to a value
213: * which could not be set via the browser. The default is true (parameters are validated).<br>
214: * <b>Note:</b> this only applies to a WebRequest created after this setting is changed. A request created
215: * with this option disabled will not only not be checked for correctness, its parameter submission
216: * order will not be guaranteed, and changing parameters will not trigger Javascript onChange / onClick events.
217: *
218: * @deprecated as of 1.6, use WebForm#newUnvalidatedRequest() to obtain a request without parameter validation.
219: **/
220: public static void setParameterValuesValidated(boolean validated) {
221: _parameterValuesValidated = validated;
222: }
223:
224: /**
225: * Returns true if images are treated as text, using their alt attributes.
226: **/
227: public static boolean getImagesTreatedAsAltText() {
228: return _imagesTreatedAsAltText;
229: }
230:
231: /**
232: * If true, tells HttpUnit to treat images with alt attributes as though they were the text
233: * value of that attribute in all searches and displays. The default is false (image text is generally ignored).
234: **/
235: public static void setImagesTreatedAsAltText(boolean asText) {
236: _imagesTreatedAsAltText = asText;
237: }
238:
239: /**
240: * If true, text matches in methods such as {@link HTMLSegment#getLinkWith} are
241: * case insensitive. The default is true (matches ignore case).
242: **/
243: public static boolean getMatchesIgnoreCase() {
244: return _matchesIgnoreCase;
245: }
246:
247: /**
248: * If true, text matches in methods such as {@link HTMLSegment#getLinkWith} are
249: * case insensitive. The default is true (matches ignore case).
250: **/
251: public static void setMatchesIgnoreCase(boolean ignoreCase) {
252: _matchesIgnoreCase = ignoreCase;
253: }
254:
255: /**
256: * Returns true if HTTP headers are to be dumped to system output.
257: **/
258: public static boolean isLoggingHttpHeaders() {
259: return _loggingHttpHeaders;
260: }
261:
262: /**
263: * If true, tells HttpUnit to log HTTP headers to system output. The default is false.
264: **/
265: public static void setLoggingHttpHeaders(boolean enabled) {
266: _loggingHttpHeaders = enabled;
267: }
268:
269: /**
270: * Returns true if HttpUnit should automatically follow page redirect requests (status 3xx).
271: * By default, this is true.
272: * @deprecated as of 1.5.3, use ClientProperties#isAutoRedirect();
273: **/
274: public static boolean getAutoRedirect() {
275: return ClientProperties.getDefaultProperties().isAutoRedirect();
276: }
277:
278: /**
279: * Determines whether HttpUnit should automatically follow page redirect requests (status 3xx).
280: * By default, this is true in order to simulate normal browser operation.
281: * @deprecated as of 1.5.3, use ClientProperties#setAutoRedirect();
282: **/
283: public static void setAutoRedirect(boolean autoRedirect) {
284: ClientProperties.getDefaultProperties().setAutoRedirect(
285: autoRedirect);
286: }
287:
288: /**
289: * Returns the delay, in milliseconds, before a redirect request is issues.
290: **/
291: public static int getRedirectDelay() {
292: return _redirectDelay;
293: }
294:
295: /**
296: * Sets the delay, in milliseconds, before a redirect request is issued. This may be necessary if the server
297: * under some cases where the server performs asynchronous processing which must be completed before the
298: * new request can be handled properly, and is taking advantage of slower processing by most user agents. It
299: * almost always indicates an error in the server design, and therefore the default delay is zero.
300: **/
301: public static void setRedirectDelay(int delayInMilliseconds) {
302: _redirectDelay = delayInMilliseconds;
303: }
304:
305: /**
306: * Returns true if HttpUnit should automatically follow page refresh requests.
307: * By default, this is false, so that programs can verify the redirect page presented
308: * to users before the browser switches to the new page.
309: * @deprecated as of 1.5.3, use ClientProperties#isAutoRefresh();
310: **/
311: public static boolean getAutoRefresh() {
312: return ClientProperties.getDefaultProperties().isAutoRefresh();
313: }
314:
315: /**
316: * Specifies whether HttpUnit should automatically follow page refresh requests.
317: * By default, this is false, so that programs can verify the redirect page presented
318: * to users before the browser switches to the new page. Setting this to true can
319: * cause an infinite loop on pages that refresh themselves.
320: * @deprecated as of 1.5.3, use ClientProperties#setAutoRefresh();
321: **/
322: public static void setAutoRefresh(boolean autoRefresh) {
323: ClientProperties.getDefaultProperties().setAutoRefresh(
324: autoRefresh);
325: }
326:
327: /**
328: * Remove an Html error listener.
329: * @deprecated as of 1.5.2, use HTMLParserfactory#removeHTMLParserListener
330: **/
331: public static void removeHtmlErrorListener(HTMLParserListener el) {
332: HTMLParserFactory.removeHTMLParserListener(el);
333: }
334:
335: /**
336: * Add an Html error listener.
337: * @deprecated as of 1.5.2, use HTMLParserfactory#addHTMLParserListener
338: **/
339: public static void addHtmlErrorListener(HTMLParserListener el) {
340: HTMLParserFactory.addHTMLParserListener(el);
341: }
342:
343: /**
344: * Get the list of Html Error Listeners
345: * @deprecated as of 1.5.2, removed with no replacement
346: **/
347: public static Vector getHtmlErrorListeners() {
348: return null;
349: }
350:
351: public static String getScriptEngineClassName() {
352: return _scriptEngineClassName;
353: }
354:
355: public static void setScriptEngineClassName(
356: String scriptEngineClassName) {
357: if (_scriptEngineClassName == null
358: || !_scriptEngineClassName
359: .equals(scriptEngineClassName)) {
360: _scriptingEngine = null;
361: }
362: _scriptEngineClassName = scriptEngineClassName;
363: }
364:
365: public static ScriptingEngineFactory getScriptingEngine() {
366: if (_scriptingEngine == null) {
367: try {
368: Class factoryClass = Class
369: .forName(_scriptEngineClassName);
370: final ScriptingEngineFactory factory = (ScriptingEngineFactory) factoryClass
371: .newInstance();
372: _scriptingEngine = factory.isEnabled() ? factory
373: : NULL_SCRIPTING_ENGINE_FACTORY;
374: _scriptingEngine
375: .setThrowExceptionsOnError(_exceptionsThrownOnScriptError);
376: } catch (ClassNotFoundException e) {
377: disableScripting(e,
378: "Unable to find scripting engine factory class ");
379: } catch (InstantiationException e) {
380: disableScripting(e,
381: "Unable to instantiate scripting engine factory class ");
382: } catch (IllegalAccessException e) {
383: disableScripting(e,
384: "Unable to create scripting engine factory class ");
385: }
386: }
387: return _scriptingEngine;
388: }
389:
390: public static void setScriptingEnabled(boolean scriptingEnabled) {
391: if (scriptingEnabled != _scriptingEnabled) {
392: _scriptingEngine = scriptingEnabled ? null
393: : NULL_SCRIPTING_ENGINE_FACTORY;
394: }
395: _scriptingEnabled = scriptingEnabled;
396: }
397:
398: public static boolean isScriptingEnabled() {
399: return _scriptingEnabled;
400: }
401:
402: /**
403: * Determines whether script errors result in exceptions or warning messages.
404: */
405: public static void setExceptionsThrownOnScriptError(
406: boolean throwExceptions) {
407: _exceptionsThrownOnScriptError = throwExceptions;
408: getScriptingEngine().setThrowExceptionsOnError(throwExceptions);
409: }
410:
411: /**
412: * Returns true if script errors cause exceptions to be thrown.
413: */
414: public static boolean getExceptionsThrownOnScriptError() {
415: return _exceptionsThrownOnScriptError;
416: }
417:
418: /**
419: * Returns the accumulated script error messages encountered. Error messages are accumulated only
420: * if 'throwExceptionsOnError' is disabled.
421: */
422: public static String[] getScriptErrorMessages() {
423: return getScriptingEngine().getErrorMessages();
424: }
425:
426: /**
427: * Clears the accumulated script error messages.
428: */
429: public static void clearScriptErrorMessages() {
430: getScriptingEngine().clearErrorMessages();
431: }
432:
433: private static void disableScripting(Exception e,
434: String errorMessage) {
435: System.err.println(errorMessage + _scriptEngineClassName);
436: System.err.println("" + e);
437: System.err.println("JavaScript execution disabled");
438: _scriptingEngine = NULL_SCRIPTING_ENGINE_FACTORY;
439: }
440:
441: //--------------------------------- private members --------------------------------------
442:
443: private static final String DEFAULT_CONTENT_TYPE = "text/html";
444:
445: private static final ScriptingEngineFactory NULL_SCRIPTING_ENGINE_FACTORY = new ScriptingEngineFactory() {
446: public boolean isEnabled() {
447: return false;
448: }
449:
450: public void associate(WebResponse response) {
451: }
452:
453: public void load(WebResponse response) {
454: }
455:
456: public void setThrowExceptionsOnError(boolean throwExceptions) {
457: }
458:
459: public boolean isThrowExceptionsOnError() {
460: return false;
461: }
462:
463: public String[] getErrorMessages() {
464: return new String[0];
465: }
466:
467: public void clearErrorMessages() {
468: }
469: };
470:
471: private static boolean _exceptionsOnErrorStatus = true;
472:
473: private static boolean _parameterValuesValidated = true;
474:
475: private static boolean _imagesTreatedAsAltText;
476:
477: private static boolean _loggingHttpHeaders;
478:
479: private static boolean _matchesIgnoreCase = true;
480:
481: private static boolean _postIncludesCharset = false;
482:
483: private static boolean _checkContentLength = false;
484:
485: private static int _redirectDelay;
486:
487: private static String _characterSet = HttpUnitUtils.DEFAULT_CHARACTER_SET;
488:
489: private static String _contentType = DEFAULT_CONTENT_TYPE;
490:
491: private static String _scriptEngineClassName;
492:
493: private static ScriptingEngineFactory _scriptingEngine;
494:
495: private static boolean _scriptingEnabled = true;
496:
497: private static boolean _exceptionsThrownOnScriptError = true;
498:
499: static {
500: reset();
501:
502: }
503: }
|