22
33
44import org .mozilla .javascript .EcmaError ;
5+ import org .openstreetmap .josm .data .Preferences ;
56import org .openstreetmap .josm .plugins .scripting .graalvm .GraalVMFacadeFactory ;
67
78import javax .script .ScriptException ;
1819import java .util .Objects ;
1920import java .util .stream .Collectors ;
2021
22+ import static org .openstreetmap .josm .tools .I18n .tr ;
23+
2124/**
2225 * A {@link JPanel} which displays an error thrown during the
2326 * execution of a script.
2427 */
2528public class ScriptErrorViewer extends JPanel {
29+ static private final String PREF_KEY_SHOW_STACKTRACE = ScriptErrorViewer .class .getName () + ".show-stack-trace-enabled" ;
30+
31+ private boolean loadFromPrefShowStackTraceEnabled () {
32+ final var prefs = Preferences .main ();
33+ return prefs .getBoolean (PREF_KEY_SHOW_STACKTRACE );
34+ }
35+
36+ private void saveToPrefShowStackTraceEnabled (boolean value ) {
37+ final var prefs = Preferences .main ();
38+ prefs .putBoolean (PREF_KEY_SHOW_STACKTRACE , value );
39+ }
2640
2741 private JTextPane paneOutput ;
2842 private final ScriptErrorViewerModel model ;
43+ private boolean showStackTrace = false ;
2944
3045 /**
3146 * Creates a new viewer with a new view model.
@@ -57,43 +72,57 @@ public ScriptErrorViewer(@NotNull final ScriptErrorViewerModel model) {
5772 return model ;
5873 }
5974
60- protected void build () {
61- setLayout (new BorderLayout ());
75+ protected JPanel buildOptionsPanel () {
76+ final var p = new JPanel ();
77+ p .setLayout (new FlowLayout (FlowLayout .LEFT ));
78+ final var cb = new JCheckBox ();
79+ p .add (cb );
80+ showStackTrace = loadFromPrefShowStackTraceEnabled ();
81+ cb .setSelected (showStackTrace );
82+ cb .addChangeListener (event -> {
83+ showStackTrace = cb .isSelected ();
84+ saveToPrefShowStackTraceEnabled (showStackTrace );
85+ refreshView ();
86+ });
87+ p .add (new JLabel (tr ("Show stack trace" )));
88+ return p ;
89+ }
90+
91+ protected JComponent buildViewerPanel () {
6292 paneOutput = new JTextPane ();
6393 paneOutput .setEditable (false );
64- JScrollPane editorScrollPane = new JScrollPane (paneOutput );
94+ final var editorScrollPane = new JScrollPane (paneOutput );
6595 editorScrollPane .setVerticalScrollBarPolicy (
6696 JScrollPane .VERTICAL_SCROLLBAR_AS_NEEDED );
6797 editorScrollPane .setHorizontalScrollBarPolicy (
6898 JScrollPane .HORIZONTAL_SCROLLBAR_AS_NEEDED );
6999 add (editorScrollPane , BorderLayout .CENTER );
70100 model .addPropertyChangeListener (new ErrorModelChangeListener ());
101+ return editorScrollPane ;
71102 }
72103
73- protected void displayPolyglotException (Throwable exception ) {
74- paneOutput .setText (formatPolyglotException (exception ));
75- paneOutput .setCaretPosition (0 );
104+ protected void build () {
105+ setLayout (new BorderLayout ());
106+ add (buildOptionsPanel (), BorderLayout .NORTH );
107+ add (buildViewerPanel (), BorderLayout .CENTER );
76108 }
77109
78- protected void displayMozillaEcmaError (EcmaError exception ) {
79- paneOutput .setText (exception .getMessage ());
80- paneOutput .setCaretPosition (0 );
110+ protected String formatMozillaEcmaError (EcmaError exception ) {
111+ return exception .getMessage ();
81112 }
82113
83- protected void displayScriptException (ScriptException exception ) {
84- paneOutput .setText (exception .getMessage ());
85- paneOutput .setCaretPosition (0 );
114+ protected String formatScriptException (ScriptException exception ) {
115+ return exception .getMessage ();
86116 }
87117
88- protected void displayGeneralException (Throwable exception ) {
118+ protected String formatGeneralException (Throwable exception ) {
89119 final var builder = new StringBuilder ();
90120 builder .append (exception .getMessage ());
91121 builder .append ("\n " );
92122 final var writer = new StringWriter ();
93123 exception .printStackTrace (new PrintWriter (writer ));
94124 builder .append (writer .getBuffer ());
95- paneOutput .setText (builder .toString ());
96- paneOutput .setCaretPosition (0 );
125+ return builder .toString ();
97126 }
98127
99128 /**
@@ -108,36 +137,54 @@ public void displayException(@Null Throwable exception) {
108137 paneOutput .setCaretPosition (0 );
109138 return ;
110139 }
111- if (GraalVMFacadeFactory .isGraalVMPresent ()) {
140+ var builder = new StringBuilder ();
141+ var mozillaEcmaError =
142+ lookupCauseByExceptionType (exception , EcmaError .class );
143+ var scriptException =
144+ lookupCauseByExceptionType (exception , ScriptException .class );
145+
146+ if (mozillaEcmaError != null ) {
147+ builder .append (formatMozillaEcmaError ((EcmaError ) mozillaEcmaError ));
148+ } else if (scriptException != null ) {
149+ builder .append (formatScriptException ((ScriptException ) scriptException ));
150+ } else if (GraalVMFacadeFactory .isGraalVMPresent ()) {
112151 try {
113152 // dynamic lookup necessary
114- final var clazz = Class .forName ("org.graalvm.polyglot.PolyglotException" );
115- final var polyglotException = lookupCauseByExceptionType (exception , clazz );
153+ var clazz = Class .forName ("org.graalvm.polyglot.PolyglotException" );
154+ var polyglotException = lookupCauseByExceptionType (exception , clazz );
116155 if (polyglotException != null ) {
117- displayPolyglotException (polyglotException );
118- return ;
156+ builder .append (formatPolyglotException (polyglotException ));
119157 }
120-
121158 } catch (ClassNotFoundException e ) {
122- return ;
159+ // ignore
123160 }
161+ } else {
162+ builder .append (formatGeneralException (exception ));
124163 }
125- final var mozillaEcmaError = lookupCauseByExceptionType (exception , EcmaError .class );
126- if (mozillaEcmaError != null ) {
127- displayMozillaEcmaError ((EcmaError ) mozillaEcmaError );
128- return ;
129- }
130- final var scriptException = lookupCauseByExceptionType (exception , ScriptException .class );
131- if (scriptException != null ) {
132- displayScriptException ((ScriptException ) scriptException );
133- return ;
164+
165+ if (showStackTrace ) {
166+ builder
167+ .append ("\n " )
168+ .append ("--------------------------------------------------------" )
169+ .append ("\n " );
170+ var sb = new StringWriter ();
171+ var writer = new PrintWriter (sb );
172+ exception .printStackTrace (writer );
173+ builder .append (sb );
134174 }
135- displayGeneralException (exception );
175+ paneOutput .setText (builder .toString ());
176+ paneOutput .setCaretPosition (0 );
177+ }
178+
179+ private void refreshView () {
180+ final var exception = model .getError ();
181+ displayException (exception );
136182 }
137183
138184 protected @ Null Throwable lookupCauseByExceptionType (Throwable t , Class <?> clazz ) {
139185 while (t != null ) {
140186 if (clazz .isInstance (t )) {
187+ // if (clazz.getName().equals(t.getClass().getName())) {
141188 break ;
142189 }
143190 t = t .getCause ();
0 commit comments