| /* |
| * Copyright 2005 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.cocoon.util.location; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.apache.commons.lang.exception.NestableRuntimeException; |
| |
| /** |
| * A cascading and located <code>RuntimeException</code>. It is also {@link MultiLocatable} to easily build |
| * location stack traces. |
| * <p> |
| * If a <code>LocatedRuntimeException</code> is built with a location and a cause which is also a |
| * <code>LocatedRuntimeException</code>, then the default behavior is to add the location to the cause |
| * exception and immediately rethrow the cause. This avoids exception nesting and builds a location |
| * stack. |
| * |
| * @since 2.1.8 |
| * @version $Id$ |
| */ |
| public class LocatedRuntimeException extends NestableRuntimeException implements LocatableException, MultiLocatable { |
| |
| private List locations; |
| |
| public LocatedRuntimeException(String message) { |
| this(message, null, null, true); |
| } |
| |
| public LocatedRuntimeException(String message, Throwable cause) throws LocatedRuntimeException { |
| this(message, cause, null, true); |
| } |
| |
| public LocatedRuntimeException(String message, Location location) { |
| this(message, null, location, true); |
| } |
| |
| public LocatedRuntimeException(String message, Throwable cause, Location location) throws LocatedRuntimeException { |
| this(message, cause, location, true); |
| } |
| |
| public LocatedRuntimeException(String message, Throwable cause, Location location, boolean rethrowLocated) |
| throws LocatedRuntimeException { |
| super(message, cause); |
| if (rethrowLocated && cause instanceof LocatedRuntimeException) { |
| LocatedRuntimeException lreCause = (LocatedRuntimeException)cause; |
| lreCause.addLocation(location); |
| // Rethrow the cause |
| throw lreCause; |
| } |
| |
| LocatedException.ensureCauseChainIsSet(cause); |
| LocatedException.addCauseLocations(this, cause); |
| addLocation(location); |
| } |
| |
| public Location getLocation() { |
| return locations == null ? null : (Location)locations.get(0); |
| } |
| |
| public List getLocations() { |
| return locations == null ? Collections.EMPTY_LIST : locations; |
| } |
| |
| public String getRawMessage() { |
| return super.getMessage(); |
| } |
| |
| public String getMessage() { |
| return LocatedException.getMessage(super.getMessage(), locations); |
| } |
| |
| public void addLocation(Location loc) { |
| if (LocationUtils.isUnknown(loc)) |
| return; |
| |
| if (locations == null) { |
| this.locations = new ArrayList(1); // Start small |
| } |
| locations.add(LocationImpl.get(loc)); |
| } |
| } |