View Javadoc

1   /*
2    * $Id: ExceptionDetailsDialog.java,v 1.12 2008/05/19 20:41:08 edankert Exp $
3    *
4    * The contents of this file are subject to the Mozilla Public License 
5    * Version 1.1 (the "License"); you may not use this file except in 
6    * compliance with the License. You may obtain a copy of the License at 
7    * http://www.mozilla.org/MPL/ 
8    *
9    * Software distributed under the License is distributed on an "AS IS" basis, 
10   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
11   * for the specific language governing rights and limitations under the License.
12   *
13   * The Original Code is XML Hammer code. (org.xmlhammer.*)
14   *
15   * The Initial Developer of the Original Code is Edwin Dankert. Portions created 
16   * by the Initial Developer are Copyright (C) 2005 - 2006 the Initial Developer. 
17   * All Rights Reserved.
18   *
19   * Contributor(s): Edwin Dankert <edankert@gmail.com>
20   */
21  package org.xmlhammer.gui.output;
22  
23  import java.awt.BorderLayout;
24  import java.awt.Color;
25  import java.awt.Dimension;
26  import java.awt.Font;
27  import java.awt.event.ActionEvent;
28  import java.awt.event.ActionListener;
29  import java.io.BufferedReader;
30  import java.io.IOException;
31  import java.io.InputStreamReader;
32  import java.net.MalformedURLException;
33  import java.net.URI;
34  
35  import javax.swing.Box;
36  import javax.swing.ImageIcon;
37  import javax.swing.JButton;
38  import javax.swing.JEditorPane;
39  import javax.swing.JFrame;
40  import javax.swing.JLabel;
41  import javax.swing.JPanel;
42  import javax.swing.JScrollPane;
43  import javax.swing.JTextArea;
44  import javax.swing.JTextField;
45  import javax.swing.border.EmptyBorder;
46  import javax.swing.text.BadLocationException;
47  import javax.swing.text.DefaultHighlighter;
48  import javax.swing.text.PlainDocument;
49  
50  import org.apache.log4j.Logger;
51  import org.bounce.FormLayout;
52  import org.bounce.com.sun.syndication.io.XmlReader;
53  import org.bounce.image.ImageLoader;
54  import org.bounce.text.LineNumberMargin;
55  import org.bounce.text.ScrollableEditorPanel;
56  import org.bounce.text.xml.XMLEditorKit;
57  import org.bounce.util.URIUtils;
58  import org.xmlhammer.gui.util.ExternalApplicationLauncher;
59  import org.xmlhammer.model.project.Exception;
60  
61  
62  class ExceptionDetailsDialog extends DetailsDialog {
63      private static final long serialVersionUID = 6396657641170177743L;
64      private static final Dimension EDITORPANE_SIZE = new Dimension( 100, 80);        
65      
66      private static final ImageIcon EDIT_ICON = ImageLoader.get().getImage("/org/xmlhammer/gui/icons/obj16/write_obj.gif");
67  
68      private static final int MAX_NO_CHARACTERS = 1000;
69      private static final int MAX_NO_LINES = 1000;
70  
71      private String title = null;
72  
73      private JTextField srcField = null;
74      private JTextField classField = null;
75  
76      private JTextField lineNumberField = null;
77      private JTextField columnNumberField = null;
78  
79      private JTextArea messageArea = null;
80      private JLabel iconLabel = null;
81  
82      private JTextField systemIdField = null;
83      private JTextField publicIdField = null;
84      private JTextArea messageField = null;
85      private JTextArea localizedMessageField = null;
86  
87      private JEditorPane contextPane = null;
88      
89      private URI uri = null;
90      private int line = -1;
91      private int column = -1;
92  
93      ExceptionDetailsDialog(JFrame parent, String title) {
94          super(parent, title);
95          
96          this.title = title;
97          
98          contextPane = new JEditorPane();
99          contextPane.setEditorKit(new XMLEditorKit());
100         contextPane.setEditable(false);
101         contextPane.setFont(new Font("monospaced", Font.PLAIN, 12));
102         contextPane.getDocument().putProperty(PlainDocument.tabSizeAttribute, new Integer(2));
103 
104         JPanel panel = new JPanel(new BorderLayout());
105 
106         messageArea = new JTextArea();
107         messageArea.setEditable(false);
108         messageArea.setLineWrap(true);
109         messageArea.setWrapStyleWord(true);
110         messageArea.setBackground(panel.getBackground());
111         messageArea.setMinimumSize(new Dimension(10,10));
112         
113         JScrollPane scroller = new JScrollPane(new ScrollableEditorPanel(contextPane));
114         scroller.setPreferredSize(AttributeNode.EDITORPANE_SIZE);
115 
116         // Add the number margin as a Row Header View
117         scroller.setRowHeaderView(new LineNumberMargin(contextPane));
118 
119         DetailsPanel context = new DetailsPanel(new BorderLayout(), "context");
120         iconLabel = new JLabel();
121         iconLabel.setBorder(new EmptyBorder(2, 0, 5, 5));
122         iconLabel.setVerticalAlignment(JLabel.TOP);
123 
124         JPanel messagePanel = new JPanel(new BorderLayout());
125         messagePanel.setBorder(new EmptyBorder(0, 2, 5, 5));
126         messagePanel.add(messageArea, BorderLayout.CENTER);
127         messagePanel.add(iconLabel, BorderLayout.WEST);
128         context.add(messagePanel, BorderLayout.NORTH);
129         
130         context.add(scroller, BorderLayout.CENTER);
131 
132         DetailsPanel details = new DetailsPanel(new FormLayout(5, 5), "details");
133 
134         srcField = new JTextField();
135         srcField.setEditable(false);
136         details.add(new JLabel("URI:"), LABEL_CONSTRAINTS);
137         details.add(srcField, FormLayout.RIGHT_FILL);
138 
139         classField = new JTextField();
140         classField.setEditable(false);
141         details.add(new JLabel("Class:"), LABEL_CONSTRAINTS);
142         details.add(classField, FormLayout.RIGHT_FILL);
143 
144         details.add(Box.createVerticalStrut(10), FormLayout.FULL);
145 
146         messageField = new JTextArea();
147         messageField.setEditable(false);
148         messageField.setLineWrap(true);
149         messageField.setWrapStyleWord(true);
150         details.add(new JLabel("Message:"), LABEL_CONSTRAINTS);
151         
152         panel = new JPanel(new BorderLayout());
153         panel.add(messageField, BorderLayout.CENTER);
154 
155         scroller = new JScrollPane( panel);
156         scroller.setPreferredSize(EDITORPANE_SIZE);
157         details.add(scroller, FormLayout.RIGHT_FILL);
158 
159         localizedMessageField = new JTextArea();
160         localizedMessageField.setEditable(false);
161         localizedMessageField.setLineWrap(true);
162         localizedMessageField.setWrapStyleWord(true);
163         details.add(new JLabel("Localized:"), LABEL_CONSTRAINTS);
164         
165         panel = new JPanel(new BorderLayout());
166         panel.add(localizedMessageField, BorderLayout.CENTER);
167 
168         scroller = new JScrollPane( panel);
169         scroller.setPreferredSize(EDITORPANE_SIZE);
170         details.add(scroller, FormLayout.RIGHT_FILL);
171 
172         details.add(Box.createVerticalStrut(10), FormLayout.FULL);
173 
174         lineNumberField = new JTextField();
175         lineNumberField.setEditable(false);
176         details.add(new JLabel("Line:"), LABEL_CONSTRAINTS);
177         details.add(lineNumberField, FormLayout.RIGHT_FILL);
178 
179         columnNumberField = new JTextField();
180         columnNumberField.setEditable(false);
181         details.add(new JLabel("Column:"), LABEL_CONSTRAINTS);
182         details.add(columnNumberField, FormLayout.RIGHT_FILL);
183 
184         details.add(Box.createVerticalStrut(10), FormLayout.FULL);
185 
186         systemIdField = new JTextField();
187         systemIdField.setEditable(false);
188         details.add(new JLabel("SystemId:"), LABEL_CONSTRAINTS);
189         details.add(systemIdField, FormLayout.RIGHT_FILL);
190 
191         publicIdField = new JTextField();
192         publicIdField.setEditable(false);
193         details.add(new JLabel("PublicId:"), LABEL_CONSTRAINTS);
194         details.add(publicIdField, FormLayout.RIGHT_FILL);
195 
196         details.add(Box.createVerticalStrut(10), FormLayout.FULL);
197 
198         addTab("Context", context);
199         addTab("Details", details);
200         
201         JButton editButton = new JButton("Edit");
202         editButton.setIcon(EDIT_ICON);
203         editButton.addActionListener( new ActionListener() { 
204             public void actionPerformed( ActionEvent e) {
205                 edit();
206             }
207         });
208         
209         addLeftButton(editButton);
210 
211         pack();
212         
213         setSize(new Dimension(500, getSize().height));
214         setLocationRelativeTo(parent);
215     }
216     
217     private void edit() {
218         ExternalApplicationLauncher.getInstance().edit(uri, line, column);
219     }
220     
221     public void setException(Exception exception, URI baseURI, ImageIcon icon) {
222         setTitle(exception.getClazz()+" - " + title);
223 
224         srcField.setText(exception.getSrc());
225         srcField.setCaretPosition(0);
226         classField.setText(exception.getClazz());
227         classField.setCaretPosition(0);
228 
229         systemIdField.setText( exception.getSystemId());
230         systemIdField.setCaretPosition(0);
231         publicIdField.setText( exception.getPublicId());
232         publicIdField.setCaretPosition(0);
233         
234         columnNumberField.setText( ""+exception.getColumn());
235         columnNumberField.setCaretPosition(0);
236         lineNumberField.setText( ""+exception.getLine());
237         lineNumberField.setCaretPosition(0);
238 
239         messageField.setText( exception.getMessage());
240         messageField.setCaretPosition(0);
241         
242         localizedMessageField.setText( exception.getLocalizedMessage());
243         localizedMessageField.setCaretPosition(0);
244         
245         messageArea.setText( exception.getMessage());
246         messageArea.setCaretPosition(0);
247         
248         iconLabel.setIcon(icon);
249 
250         try {
251             line = exception.getLine();
252             column = exception.getColumn();
253 
254             uri = baseURI;
255             
256             if (exception.getSystemId() != null) {
257                 uri = URIUtils.createURI(exception.getSystemId());
258             }
259 
260             BufferedReader reader = null;
261             String line = null;
262             
263             try {
264                 reader = new BufferedReader(new XmlReader(uri.toURL()));
265                 line = reader.readLine();
266             } catch (java.lang.Exception ex) {
267                 ex.printStackTrace();
268                 // Assume UTF-8 encoding ...
269                 reader = new BufferedReader(new InputStreamReader(uri.toURL().openStream(), "UTF-8"));
270                 line = reader.readLine();
271             }
272             
273             StringBuilder builder = new StringBuilder();
274             int index = 1;
275             int position = -1;
276             
277             while (line != null) {
278                 if (exception.getLine() == index) {
279                     if (line.length() > MAX_NO_CHARACTERS) {
280                         // everything on one line
281                         builder = new StringBuilder(line.substring(Math.max(1, exception.getColumn()-(MAX_NO_CHARACTERS/2)), Math.min(line.length(), exception.getColumn()+(MAX_NO_CHARACTERS/2))));
282                         
283                         if (exception.getColumn() > (MAX_NO_CHARACTERS/2)) {
284                             position = (MAX_NO_CHARACTERS/2);
285                         } else {
286                             position = exception.getColumn();
287                         }
288                         break;
289                     }
290 
291                     position = builder.length()+exception.getColumn();
292                 }
293 
294                 if (index >= Math.max(1, exception.getLine()-(MAX_NO_LINES/2))) {
295                     builder.append(line);
296                     builder.append("\n");
297                 }
298                 
299                 if (index > Math.max((MAX_NO_LINES/2), exception.getLine()+(MAX_NO_LINES/2))) {
300                     break;
301                 }
302                 
303                 line = reader.readLine();
304                 index++;
305             }
306             
307             reader.close();
308             
309             contextPane.setText(builder.toString());
310             try {
311                 if (position > 0) {
312                     contextPane.getHighlighter().addHighlight(position-2, position-1, new DefaultHighlighter.DefaultHighlightPainter(new Color(255, 200, 200)));
313                     contextPane.getHighlighter().addHighlight(builder.lastIndexOf("<", position-2), position-2, new DefaultHighlighter.DefaultHighlightPainter(new Color(255, 225, 225)));
314                 }
315             } catch (BadLocationException e) {
316                 Logger.getLogger(getClass()).debug(e);
317             }
318             contextPane.setCaretPosition(Math.max(0, position-1));
319 
320         } catch (MalformedURLException e) {
321             Logger.getLogger(getClass()).debug(e);
322         } catch (IOException e) {
323             e.printStackTrace();
324             Logger.getLogger(getClass()).debug(e);
325         }
326     }
327     
328     @Override
329     protected String getBaseHelpID() {
330         return "output.result.error";
331     }
332 }