1 /*
2 * ========================================================================
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * ========================================================================
20 */
21 package org.apache.cactus.internal.client;
22
23 import org.apache.cactus.internal.WebTestResult;
24
25 /**
26 * Parse a string representing a Test result and transform it into a
27 * <code>WebTestResult</code> object.
28 *
29 * @see WebTestResult
30 *
31 * @version $Id: WebTestResultParser.java 238991 2004-05-22 11:34:50Z vmassol $
32 */
33 public class WebTestResultParser
34 {
35 /**
36 * Parsed exception class name.
37 */
38 protected String exceptionClassname;
39
40 /**
41 * Parsed exception message.
42 */
43 protected String exceptionMessage;
44
45 /**
46 * Parsed exception stack trace.
47 */
48 protected String exceptionStacktrace;
49
50 /**
51 * Parse a string and transform it into a <code>WebTestResult</code> object.
52 *
53 * @param theData the string to parse
54 * @return the <code>WebTestResult</code> object corresponding to the data
55 * string
56 * @throws ParsingException if an error happens during parsing
57 */
58 public WebTestResult parse(String theData) throws ParsingException
59 {
60 String buffer;
61 WebTestResult result;
62
63 buffer = readRootElement(theData);
64
65 if (buffer.length() == 0)
66 {
67 result = new WebTestResult();
68 }
69 else
70 {
71 buffer = readExceptionClassname(buffer);
72 buffer = readExceptionMessage(buffer);
73 buffer = readExceptionStacktrace(buffer);
74 result = new WebTestResult(this.exceptionClassname,
75 this.exceptionMessage, this.exceptionStacktrace);
76 }
77
78 return result;
79 }
80
81 /**
82 * Read the {@link WebTestResult#XML_ROOT_ELEMENT} portion.
83 *
84 * @param theData the string buffer to parse
85 * @return the string buffer minus what has been read
86 * @throws ParsingException if an error happens during parsing
87 */
88 protected String readRootElement(String theData) throws ParsingException
89 {
90 String startRootString = "<" + WebTestResult.XML_ROOT_ELEMENT + ">";
91 String endRootString = "</" + WebTestResult.XML_ROOT_ELEMENT + ">";
92 String buffer;
93
94 // It is possible that some end of line character are inserted at the
95 // end of the string. This is valid, which is why we trim the string
96 // before perfoming the checks.
97 String trimmedData = theData.trim();
98
99 if (trimmedData.startsWith(startRootString)
100 && trimmedData.endsWith(endRootString))
101 {
102 buffer = trimmedData.substring(startRootString.length(),
103 trimmedData.length() - endRootString.length());
104 }
105 else
106 {
107 throw new ParsingException(formatError(theData));
108 }
109
110 return buffer;
111 }
112
113 /**
114 * Read the {@link WebTestResult#XML_EXCEPTION_CLASSNAME_ATTRIBUTE} portion
115 * and extract the exception classname.
116 *
117 * @param theData the string buffer to parse
118 * @return the string buffer minus what has been read
119 * @throws ParsingException if an error happens during parsing
120 */
121 protected String readExceptionClassname(String theData)
122 throws ParsingException
123 {
124 String startString = "<" + WebTestResult.XML_EXCEPTION_ELEMENT + " "
125 + WebTestResult.XML_EXCEPTION_CLASSNAME_ATTRIBUTE + "=\"";
126 String endString = "</" + WebTestResult.XML_EXCEPTION_ELEMENT + ">";
127 String buffer;
128
129 if (theData.startsWith(startString) && theData.endsWith(endString))
130 {
131 int pos = theData.indexOf('\"', startString.length());
132
133 this.exceptionClassname = theData.substring(startString.length(),
134 pos);
135 buffer = theData.substring(startString.length()
136 + this.exceptionClassname.length() + 2,
137 theData.length() - endString.length());
138 }
139 else
140 {
141 throw new ParsingException(formatError(theData));
142 }
143
144 return buffer;
145 }
146
147 /**
148 * Read the {@link WebTestResult#XML_EXCEPTION_MESSAGE_ELEMENT} portion
149 * and extract the exception message.
150 *
151 * @param theData the string buffer to parse
152 * @return the string buffer minus what has been read
153 * @throws ParsingException if an error happens during parsing
154 */
155 protected String readExceptionMessage(String theData)
156 throws ParsingException
157 {
158 String startString = "<" + WebTestResult.XML_EXCEPTION_MESSAGE_ELEMENT
159 + "><![CDATA[";
160 String endString = "]]></"
161 + WebTestResult.XML_EXCEPTION_MESSAGE_ELEMENT + ">";
162 String buffer;
163
164 if (theData.startsWith(startString))
165 {
166 int pos = theData.indexOf(endString, startString.length());
167
168 this.exceptionMessage = theData.substring(startString.length(),
169 pos);
170 buffer = theData.substring(pos + endString.length());
171 }
172 else
173 {
174 throw new ParsingException(formatError(theData));
175 }
176
177 return buffer;
178 }
179
180 /**
181 * Read the {@link WebTestResult#XML_EXCEPTION_STACKTRACE_ELEMENT} portion
182 * and extract the exception stacktrace.
183 *
184 * @param theData the string buffer to parse
185 * @return the string buffer minus what has been read
186 * @throws ParsingException if an error happens during parsing
187 */
188 protected String readExceptionStacktrace(String theData)
189 throws ParsingException
190 {
191 String startString = "<"
192 + WebTestResult.XML_EXCEPTION_STACKTRACE_ELEMENT + "><![CDATA[";
193 String endString = "]]></"
194 + WebTestResult.XML_EXCEPTION_STACKTRACE_ELEMENT + ">";
195 String buffer;
196
197 if (theData.startsWith(startString))
198 {
199 int pos = theData.indexOf(endString, startString.length());
200
201 this.exceptionStacktrace = theData.substring(startString.length(),
202 pos);
203 buffer = theData.substring(pos + endString.length());
204 }
205 else
206 {
207 throw new ParsingException(formatError(theData));
208 }
209
210 return buffer;
211 }
212
213 /**
214 * @param theData the data to format
215 * @return the first 100 characters (or less if the data has fewer
216 * characters) of the invalid data as it can be very big
217 */
218 private String formatError(String theData)
219 {
220 int nbChars = theData.length() > 100 ? 100 : theData.length();
221
222 return "Not a valid response. First " + nbChars
223 + " characters of the reponse: ["
224 + theData.substring(0, nbChars) + "]";
225 }
226 }