001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether;
020
021/**
022 * A trace of nested requests that are performed by the repository system. This trace information can be used to
023 * correlate repository events with higher level operations in the application code that eventually caused the events. A
024 * single trace can carry an arbitrary object as data which is meant to describe a request/operation that is currently
025 * executed. For call hierarchies within the repository system itself, this data will usually be the {@code *Request}
026 * object that is currently processed. When invoking methods on the repository system, client code may provide a request
027 * trace that has been prepopulated with whatever data is useful for the application to indicate its state for later
028 * evaluation when processing the repository events.
029 *
030 * @see RepositoryEvent#getTrace()
031 */
032public class RequestTrace {
033
034    private final RequestTrace parent;
035
036    private final Object data;
037
038    /**
039     * Creates a child of the specified request trace. This method is basically a convenience that will invoke
040     * {@link RequestTrace#newChild(Object) parent.newChild()} when the specified parent trace is not {@code null} or
041     * otherwise instantiante a new root trace.
042     *
043     * @param parent The parent request trace, may be {@code null}.
044     * @param data The data to associate with the child trace, may be {@code null}.
045     * @return The child trace, never {@code null}.
046     */
047    public static RequestTrace newChild(RequestTrace parent, Object data) {
048        if (parent == null) {
049            return new RequestTrace(data);
050        }
051        return parent.newChild(data);
052    }
053
054    /**
055     * Creates a new root trace with the specified data.
056     *
057     * @param data The data to associate with the trace, may be {@code null}.
058     */
059    public RequestTrace(Object data) {
060        this(null, data);
061    }
062
063    /**
064     * Creates a new trace with the specified data and parent
065     *
066     * @param parent The parent trace, may be {@code null} for a root trace.
067     * @param data The data to associate with the trace, may be {@code null}.
068     */
069    protected RequestTrace(RequestTrace parent, Object data) {
070        this.parent = parent;
071        this.data = data;
072    }
073
074    /**
075     * Gets the data associated with this trace.
076     *
077     * @return The data associated with this trace or {@code null} if none.
078     */
079    public final Object getData() {
080        return data;
081    }
082
083    /**
084     * Gets the parent of this trace.
085     *
086     * @return The parent of this trace or {@code null} if this is the root of the trace stack.
087     */
088    public final RequestTrace getParent() {
089        return parent;
090    }
091
092    /**
093     * Creates a new child of this trace.
094     *
095     * @param data The data to associate with the child, may be {@code null}.
096     * @return The child trace, never {@code null}.
097     */
098    public RequestTrace newChild(Object data) {
099        return new RequestTrace(this, data);
100    }
101
102    @Override
103    public String toString() {
104        return String.valueOf(getData());
105    }
106}