001// Copyright 2006 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5.commons.internal.util;
016
017import org.apache.tapestry5.commons.Locatable;
018import org.apache.tapestry5.commons.Location;
019
020/**
021 * Exception class used as a replacement for {@link java.lang.RuntimeException} when the exception is related to a
022 * particular location.
023 */
024public class TapestryException extends RuntimeException implements Locatable
025{
026    private static final long serialVersionUID = 6396903640977182682L;
027
028    private transient final Location location;
029
030    /**
031     * @param message  a message (may be null)
032     * @param location implements {@link Location} or {@link Locatable}
033     * @param cause    if not null, the root cause of the exception
034     */
035    public TapestryException(String message, Object location, Throwable cause)
036    {
037        this(message, InternalCommonsUtils.locationOf(location), cause);
038    }
039
040    /**
041     * @param message a message (may be null)
042     * @param cause   if not null, the root cause of the exception, also used to set the location
043     */
044    public TapestryException(String message, Throwable cause)
045    {
046        this(message, cause, cause);
047    }
048
049    /**
050     * @param message  a message (may be null)
051     * @param location location to associated with the exception, or null if not known
052     * @param cause    if not null, the root cause of the exception
053     */
054    public TapestryException(String message, Location location, Throwable cause)
055    {
056        super(message, cause);
057
058        this.location = location;
059    }
060
061    @Override
062    public Location getLocation()
063    {
064        return location;
065    }
066
067    @Override
068    public String toString()
069    {
070        if (location == null) return super.toString();
071
072        return String.format("%s [at %s]", super.toString(), location);
073    }
074
075}