View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.struts.flow.core.location;
17  
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.apache.commons.lang.exception.NestableRuntimeException;
23  
24  /***
25   * A cascading and located <code>RuntimeException</code>. It is also {@link MultiLocatable} to easily build
26   * location stack traces.
27   * <p>
28   * If a <code>LocatedRuntimeException</code> is built with a location and a cause which is also a
29   * <code>LocatedRuntimeException</code>, then the default behavior is to add the location to the cause
30   * exception and immediately rethrow the cause. This avoids exception nesting and builds a location
31   * stack.
32   * 
33   * @since 2.1.8
34   * @version $Id: LocatedRuntimeException.java 290845 2005-09-21 22:04:27Z sylvain $
35   */
36  public class LocatedRuntimeException extends NestableRuntimeException implements LocatableException, MultiLocatable {
37      
38      private List locations;
39  
40      public LocatedRuntimeException(String message) {
41          this(message, null, null, true);
42      }
43      
44      public LocatedRuntimeException(String message, Throwable cause) throws LocatedRuntimeException {
45          this(message, cause, null, true);
46      }
47      
48      public LocatedRuntimeException(String message, Location location) {
49          this(message, null, location, true);
50      }
51      
52      public LocatedRuntimeException(String message, Throwable cause, Location location) throws LocatedRuntimeException {
53          this(message, cause, location, true);
54      }
55  
56      public LocatedRuntimeException(String message, Throwable cause, Location location, boolean rethrowLocated)
57          throws LocatedRuntimeException {
58          super(message, cause);
59          if (rethrowLocated && cause instanceof LocatedRuntimeException) {
60              LocatedRuntimeException lreCause = (LocatedRuntimeException)cause;
61              lreCause.addLocation(location);
62              // Rethrow the cause
63              throw lreCause;
64          }
65  
66          LocatedException.ensureCauseChainIsSet(cause);
67          LocatedException.addCauseLocations(this, cause);
68          addLocation(location);
69      }
70  
71      public Location getLocation() {
72          return locations == null ? null : (Location)locations.get(0);
73      }
74  
75      public List getLocations() {
76          return locations == null ? Collections.EMPTY_LIST : locations;
77      }
78  
79      public String getRawMessage() {
80          return super.getMessage();
81      }
82  
83      public String getMessage() {
84          return LocatedException.getMessage(super.getMessage(), locations);
85      }
86      
87      public void addLocation(Location loc) {
88          if (LocationUtils.isUnknown(loc))
89              return;
90  
91          if (locations == null) {
92              this.locations = new ArrayList(1); // Start small
93          }
94          locations.add(LocationImpl.get(loc));
95      }
96  }