001: /*
002: * ========================================================================
003: *
004: * Copyright 2001-2004 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * ========================================================================
019: */
020: package org.apache.cactus.internal.client;
021:
022: import org.apache.cactus.internal.WebTestResult;
023:
024: /**
025: * Parse a string representing a Test result and transform it into a
026: * <code>WebTestResult</code> object.
027: *
028: * @see WebTestResult
029: *
030: * @version $Id: WebTestResultParser.java 238991 2004-05-22 11:34:50Z vmassol $
031: */
032: public class WebTestResultParser {
033: /**
034: * Parsed exception class name
035: */
036: protected String exceptionClassname;
037:
038: /**
039: * Parsed exception message
040: */
041: protected String exceptionMessage;
042:
043: /**
044: * Parsed exception stack trace
045: */
046: protected String exceptionStacktrace;
047:
048: /**
049: * Parse a string and transform it into a <code>WebTestResult</code> object.
050: *
051: * @param theData the string to parse
052: * @return the <code>WebTestResult</code> object corresponding to the data
053: * string
054: * @exception ParsingException if an error happens during parsing
055: */
056: public WebTestResult parse(String theData) throws ParsingException {
057: String buffer;
058: WebTestResult result;
059:
060: buffer = readRootElement(theData);
061:
062: if (buffer.length() == 0) {
063: result = new WebTestResult();
064: } else {
065: buffer = readExceptionClassname(buffer);
066: buffer = readExceptionMessage(buffer);
067: buffer = readExceptionStacktrace(buffer);
068: result = new WebTestResult(this .exceptionClassname,
069: this .exceptionMessage, this .exceptionStacktrace);
070: }
071:
072: return result;
073: }
074:
075: /**
076: * Read the {@link WebTestResult#XML_ROOT_ELEMENT} portion.
077: *
078: * @param theData the string buffer to parse
079: * @return the string buffer minus what has been read
080: * @exception ParsingException if an error happens during parsing
081: */
082: protected String readRootElement(String theData)
083: throws ParsingException {
084: String startRootString = "<" + WebTestResult.XML_ROOT_ELEMENT
085: + ">";
086: String endRootString = "</" + WebTestResult.XML_ROOT_ELEMENT
087: + ">";
088: String buffer;
089:
090: // It is possible that some end of line character are inserted at the
091: // end of the string. This is valid, which is why we trim the string
092: // before perfoming the checks.
093: String trimmedData = theData.trim();
094:
095: if (trimmedData.startsWith(startRootString)
096: && trimmedData.endsWith(endRootString)) {
097: buffer = trimmedData.substring(startRootString.length(),
098: trimmedData.length() - endRootString.length());
099: } else {
100: throw new ParsingException(formatError(theData));
101: }
102:
103: return buffer;
104: }
105:
106: /**
107: * Read the {@link WebTestResult#XML_EXCEPTION_CLASSNAME_ATTRIBUTE} portion
108: * and extract the exception classname.
109: *
110: * @param theData the string buffer to parse
111: * @return the string buffer minus what has been read
112: * @exception ParsingException if an error happens during parsing
113: */
114: protected String readExceptionClassname(String theData)
115: throws ParsingException {
116: String startString = "<" + WebTestResult.XML_EXCEPTION_ELEMENT
117: + " " + WebTestResult.XML_EXCEPTION_CLASSNAME_ATTRIBUTE
118: + "=\"";
119: String endString = "</" + WebTestResult.XML_EXCEPTION_ELEMENT
120: + ">";
121: String buffer;
122:
123: if (theData.startsWith(startString)
124: && theData.endsWith(endString)) {
125: int pos = theData.indexOf('\"', startString.length());
126:
127: this .exceptionClassname = theData.substring(startString
128: .length(), pos);
129: buffer = theData.substring(startString.length()
130: + this .exceptionClassname.length() + 2, theData
131: .length()
132: - endString.length());
133: } else {
134: throw new ParsingException(formatError(theData));
135: }
136:
137: return buffer;
138: }
139:
140: /**
141: * Read the {@link WebTestResult#XML_EXCEPTION_MESSAGE_ELEMENT} portion
142: * and extract the exception message.
143: *
144: * @param theData the string buffer to parse
145: * @return the string buffer minus what has been read
146: * @exception ParsingException if an error happens during parsing
147: */
148: protected String readExceptionMessage(String theData)
149: throws ParsingException {
150: String startString = "<"
151: + WebTestResult.XML_EXCEPTION_MESSAGE_ELEMENT
152: + "><![CDATA[";
153: String endString = "]]></"
154: + WebTestResult.XML_EXCEPTION_MESSAGE_ELEMENT + ">";
155: String buffer;
156:
157: if (theData.startsWith(startString)) {
158: int pos = theData.indexOf(endString, startString.length());
159:
160: this .exceptionMessage = theData.substring(startString
161: .length(), pos);
162: buffer = theData.substring(pos + endString.length());
163: } else {
164: throw new ParsingException(formatError(theData));
165: }
166:
167: return buffer;
168: }
169:
170: /**
171: * Read the {@link WebTestResult#XML_EXCEPTION_STACKTRACE_ELEMENT} portion
172: * and extract the exception stacktrace.
173: *
174: * @param theData the string buffer to parse
175: * @return the string buffer minus what has been read
176: * @exception ParsingException if an error happens during parsing
177: */
178: protected String readExceptionStacktrace(String theData)
179: throws ParsingException {
180: String startString = "<"
181: + WebTestResult.XML_EXCEPTION_STACKTRACE_ELEMENT
182: + "><![CDATA[";
183: String endString = "]]></"
184: + WebTestResult.XML_EXCEPTION_STACKTRACE_ELEMENT + ">";
185: String buffer;
186:
187: if (theData.startsWith(startString)) {
188: int pos = theData.indexOf(endString, startString.length());
189:
190: this .exceptionStacktrace = theData.substring(startString
191: .length(), pos);
192: buffer = theData.substring(pos + endString.length());
193: } else {
194: throw new ParsingException(formatError(theData));
195: }
196:
197: return buffer;
198: }
199:
200: /**
201: * @param theData the data to format
202: * @return the first 100 characters (or less if the data has fewer
203: * characters) of the invalid data as it can be very big
204: */
205: private String formatError(String theData) {
206: int nbChars = theData.length() > 100 ? 100 : theData.length();
207:
208: return "Not a valid response. First " + nbChars
209: + " characters of the reponse: ["
210: + theData.substring(0, nbChars) + "]";
211: }
212: }
|