001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.util.location;
018:
019: import java.util.ArrayList;
020: import java.util.Collections;
021: import java.util.List;
022:
023: import org.apache.commons.lang.exception.NestableRuntimeException;
024:
025: /**
026: * A cascading and located <code>RuntimeException</code>. It is also {@link MultiLocatable} to easily build
027: * location stack traces.
028: * <p>
029: * If a <code>LocatedRuntimeException</code> is built with a location and a cause which is also a
030: * <code>LocatedRuntimeException</code>, then the default behavior is to add the location to the cause
031: * exception and immediately rethrow the cause. This avoids exception nesting and builds a location
032: * stack.
033: *
034: * @since 2.1.8
035: * @version $Id: LocatedRuntimeException.java 446917 2006-09-16 19:10:40Z vgritsenko $
036: */
037: public class LocatedRuntimeException extends NestableRuntimeException
038: implements LocatableException, MultiLocatable {
039:
040: private List locations;
041:
042: public LocatedRuntimeException(String message) {
043: this (message, null, null, true);
044: }
045:
046: public LocatedRuntimeException(String message, Throwable cause)
047: throws LocatedRuntimeException {
048: this (message, cause, null, true);
049: }
050:
051: public LocatedRuntimeException(String message, Location location) {
052: this (message, null, location, true);
053: }
054:
055: public LocatedRuntimeException(String message, Throwable cause,
056: Location location) throws LocatedRuntimeException {
057: this (message, cause, location, true);
058: }
059:
060: public LocatedRuntimeException(String message, Throwable cause,
061: Location location, boolean rethrowLocated)
062: throws LocatedRuntimeException {
063: super (message, cause);
064: if (rethrowLocated && cause instanceof LocatedRuntimeException) {
065: LocatedRuntimeException lreCause = (LocatedRuntimeException) cause;
066: lreCause.addLocation(location);
067: // Rethrow the cause
068: throw lreCause;
069: }
070:
071: LocatedException.ensureCauseChainIsSet(cause);
072: LocatedException.addCauseLocations(this , cause);
073: addLocation(location);
074: }
075:
076: public Location getLocation() {
077: return locations == null ? null : (Location) locations.get(0);
078: }
079:
080: public List getLocations() {
081: return locations == null ? Collections.EMPTY_LIST : locations;
082: }
083:
084: public String getRawMessage() {
085: return super .getMessage();
086: }
087:
088: public String getMessage() {
089: return LocatedException.getMessage(super .getMessage(),
090: locations);
091: }
092:
093: public void addLocation(Location loc) {
094: if (LocationUtils.isUnknown(loc)) {
095: return;
096: }
097:
098: if (locations == null) {
099: this .locations = new ArrayList(1); // Start small
100: }
101: locations.add(LocationImpl.get(loc));
102: }
103: }
|