2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

View Javadoc

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 }