1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.jshell;
27
28import jdk.jshell.Snippet.Status;
29
30/**
31 * A description of a change to a Snippet. These are generated by direct changes
32 * to state with {@link JShell#eval(java.lang.String) JShell.eval(String)} or
33 * {@link JShell#drop(jdk.jshell.Snippet) JShell.drop(Snippet)},
34 * or indirectly by these same methods as
35 * dependencies change or Snippets are overwritten. For direct changes, the
36 * {@link SnippetEvent#causeSnippet()} is {@code null}.
37 * <p>
38 * {@code SnippetEvent} is immutable: an access to
39 * any of its methods will always return the same result.
40 * and thus is thread-safe.
41 *
42 * @author Robert Field
43 * @since 9
44 */
45public class SnippetEvent {
46
47    SnippetEvent(Snippet snippet, Status previousStatus, Status status,
48            boolean isSignatureChange, Snippet causeSnippet,
49            String value, JShellException exception) {
50        this.snippet = snippet;
51        this.previousStatus = previousStatus;
52        this.status = status;
53        this.isSignatureChange = isSignatureChange;
54        this.causeSnippet = causeSnippet;
55        this.value = value;
56        this.exception = exception;
57    }
58
59    private final Snippet snippet;
60    private final Status previousStatus;
61    private final Status status;
62    private final boolean isSignatureChange;
63    private final Snippet causeSnippet;
64    private final String value;
65    private final JShellException exception;
66
67    /**
68     * The Snippet which has changed
69     * @return the return the Snippet whose {@code Status} has changed.
70     */
71    public Snippet snippet() {
72        return snippet;
73    }
74
75    /**
76     * The status before the transition. If this event describes a Snippet
77     * creation return {@link Snippet.Status#NONEXISTENT NONEXISTENT}.
78     * @return the previousStatus
79     */
80    public Status previousStatus() {
81        return previousStatus;
82    }
83
84    /**
85     * The after status. Note: this may be the same as the previous status (not
86     * all changes cause a {@code Status} change.
87     * @return the status
88     */
89    public Status status() {
90        return status;
91    }
92
93    /**
94     * Indicates whether the signature has changed. Coming in or out of
95     * {@linkplain Status#isDefined() definition} is always a signature change.
96     * An overwritten Snippet
97     * {@link jdk.jshell.Snippet.Status#OVERWRITTEN (status == OVERWRITTEN)}
98     * is always {@code false} as responsibility for the
99     * definition has passed to the overwriting definition.
100     *
101     * @return {@code true} if the signature changed; otherwise {@code false}
102     */
103    public boolean isSignatureChange() {
104        return isSignatureChange;
105    }
106
107    /**
108     * Either the snippet whose change caused this update or
109     * {@code null}. This returns {@code null} if this change is the
110     * creation of a new Snippet via
111     * {@link jdk.jshell.JShell#eval(java.lang.String) eval} or it is the
112     * explicit drop of a Snippet with
113     * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop}.
114     *
115     * @return the Snippet which caused this change or {@code null} if
116     * directly caused by an API action.
117     */
118    public Snippet causeSnippet() {
119        return causeSnippet;
120    }
121
122    /**
123     * An instance of {@link jdk.jshell.UnresolvedReferenceException}, if an unresolved reference was
124     * encountered, or an instance of {@link jdk.jshell.EvalException} if an exception was thrown
125     * during execution, otherwise {@code null}.
126     * @return the exception or {@code null}.
127     */
128    public JShellException exception() {
129        return exception;
130    }
131
132    /**
133     * The result value of successful run. The value is null if not executed
134     * or an exception was thrown.
135     * @return the value or {@code null}.
136     */
137    public String value() {
138        return value;
139    }
140
141    /**
142     * Return a string representation of the event
143     * @return a descriptive representation of the SnippetEvent
144     */
145    @Override
146    public String toString() {
147        return "SnippetEvent(snippet=" + snippet +
148                ",previousStatus=" + previousStatus +
149                ",status=" + status +
150                ",isSignatureChange=" + isSignatureChange +
151                ",causeSnippet" + causeSnippet +
152                (value == null? "" : "value=" + value) +
153                (exception == null? "" : "exception=" + exception) +
154                ")";
155    }
156}
157