1 /*
2 * XsltEditor.java
3 * Copyright (c) 2002 Raben Systems, Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of Raben Systems, Inc. nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Created on March 20, 2002, 12:29 PM
31 */
32
33 package com.raben.tools.xslteditor;
34 import javax.swing.*;
35 import java.awt.image.BufferedImage;
36 import java.awt.event.*;
37 import javax.swing.event.*;
38 import java.io.*;
39 import java.net.*;
40 import java.util.*;
41 import java.awt.Toolkit;
42 import java.awt.Dimension;
43 import java.awt.Point;
44 import org.w3c.dom.*;
45 import org.xml.sax.*;
46 import javax.xml.transform.*;
47 import javax.xml.transform.dom.*;
48 import javax.xml.transform.stream.*;
49 import javax.xml.parsers.*;
50 import java.beans.*;
51 import java.awt.datatransfer.*;
52 import javax.swing.undo.*;
53 import javax.swing.text.*;
54 import javax.swing.text.html.*;
55
56 /***
57 * Simple tool for loading, displaying, editing, and transforming
58 * XML files with XSLT
59 * @author Vern Raben
60 */
61 public class XsltEditor extends javax.swing.JFrame implements PropertyChangeListener {
62
63 /*** Creates new form XsltEditor */
64 public XsltEditor() {
65 initComponents();
66 initTabbedPane();
67
68 // Add Xml Editor Undo and Redo Action classes
69 xmlUndoAction=new XmlUndoAction();
70 xmlRedoAction=new XmlRedoAction();
71 xmlEditorPane.setContentType("text/xml");
72 xmlEditorPane.getDocument().addUndoableEditListener(new XmlUndoableEditListener());
73
74 // Add Xslt Editor Undo and Redo Action classes
75 xsltUndoAction=new XsltUndoAction();
76 xsltRedoAction=new XsltRedoAction();
77 xsltEditorPane.getDocument().addUndoableEditListener(new XsltUndoableEditListener());
78
79 // Load props containing previous directories and urls used
80 loadProps();
81
82 // Create and xml document builder factory
83 documentBuilderFactory=DocumentBuilderFactory.newInstance();
84 documentBuilderFactory.setNamespaceAware(true);
85 try {
86 documentBuilder=documentBuilderFactory.newDocumentBuilder();
87 }
88 catch (ParserConfigurationException e) {
89 log(e.getMessage());
90 tabbedPane.setSelectedIndex(3);
91 }
92
93 if (! "yes".equals(licenseAccepted)) {
94 showLicenseDialog();
95 }
96
97 xsltEditor=this; // Reference to self for Inner class access
98
99 }
100
101 /*** This method is called from within the constructor to
102 * initialize the form.
103 * WARNING: Do NOT modify this code. The content of this method is
104 * always regenerated by the Form Editor.
105 */
106 private void initComponents() {//GEN-BEGIN:initComponents
107 menuBar = new javax.swing.JMenuBar();
108 fileMenu = new javax.swing.JMenu();
109 openXmlFileMenuItem = new javax.swing.JMenuItem();
110 openXmlUrlMenuItem = new javax.swing.JMenuItem();
111 saveXmlMenuItem = new javax.swing.JMenuItem();
112 jSeparator1 = new javax.swing.JSeparator();
113 openXsltFileMenuItem = new javax.swing.JMenuItem();
114 openXsltUrlMenuItem = new javax.swing.JMenuItem();
115 saveXsltFileMenuItem = new javax.swing.JMenuItem();
116 jSeparator2 = new javax.swing.JSeparator();
117 exitMenuItem = new javax.swing.JMenuItem();
118 editMenu = new javax.swing.JMenu();
119 undoMenuItem = new javax.swing.JMenuItem();
120 redoMenuItem = new javax.swing.JMenuItem();
121 jSeparator3 = new javax.swing.JSeparator();
122 cutMenuItem = new javax.swing.JMenuItem();
123 copyMenuItem = new javax.swing.JMenuItem();
124 pasteMenuItem = new javax.swing.JMenuItem();
125 deleteMenuItem = new javax.swing.JMenuItem();
126 helpMenu = new javax.swing.JMenu();
127 contentsMenuItem = new javax.swing.JMenuItem();
128 aboutMenuItem = new javax.swing.JMenuItem();
129 tabbedPane = new javax.swing.JTabbedPane();
130 xmlScrollPane = new javax.swing.JScrollPane();
131 xmlEditorPane = new javax.swing.JEditorPane();
132 xsltScrollPane = new javax.swing.JScrollPane();
133 xsltEditorPane = new javax.swing.JEditorPane();
134 resultScrollPane = new javax.swing.JScrollPane();
135 resultEditorPane = new javax.swing.JEditorPane();
136 outputScrollPane = new javax.swing.JScrollPane();
137 outputEditorPane = new javax.swing.JEditorPane();
138 controlPanel = new javax.swing.JPanel();
139 transformButton = new javax.swing.JButton();
140 clearButton = new javax.swing.JButton();
141
142 fileMenu.setText("File");
143 openXmlFileMenuItem.setText("Open XML File");
144 openXmlFileMenuItem.addActionListener(new java.awt.event.ActionListener() {
145 public void actionPerformed(java.awt.event.ActionEvent evt) {
146 openXmlFileMenuItemActionPerformed(evt);
147 }
148 });
149
150 fileMenu.add(openXmlFileMenuItem);
151 openXmlUrlMenuItem.setText("Open XML URL");
152 openXmlUrlMenuItem.addActionListener(new java.awt.event.ActionListener() {
153 public void actionPerformed(java.awt.event.ActionEvent evt) {
154 openXmlUrlMenuItemActionPerformed(evt);
155 }
156 });
157
158 fileMenu.add(openXmlUrlMenuItem);
159 saveXmlMenuItem.setText("Save XML File");
160 saveXmlMenuItem.addActionListener(new java.awt.event.ActionListener() {
161 public void actionPerformed(java.awt.event.ActionEvent evt) {
162 saveXmlMenuItemActionPerformed(evt);
163 }
164 });
165
166 fileMenu.add(saveXmlMenuItem);
167 fileMenu.add(jSeparator1);
168 openXsltFileMenuItem.setText("Open XSLT File");
169 openXsltFileMenuItem.addActionListener(new java.awt.event.ActionListener() {
170 public void actionPerformed(java.awt.event.ActionEvent evt) {
171 openXsltFileMenuItemActionPerformed(evt);
172 }
173 });
174
175 fileMenu.add(openXsltFileMenuItem);
176 openXsltUrlMenuItem.setText("Open XSLT URL");
177 openXsltUrlMenuItem.addActionListener(new java.awt.event.ActionListener() {
178 public void actionPerformed(java.awt.event.ActionEvent evt) {
179 openXsltUrlMenuItemActionPerformed(evt);
180 }
181 });
182
183 fileMenu.add(openXsltUrlMenuItem);
184 saveXsltFileMenuItem.setText("Save XSLT File");
185 saveXsltFileMenuItem.addActionListener(new java.awt.event.ActionListener() {
186 public void actionPerformed(java.awt.event.ActionEvent evt) {
187 saveXsltFileMenuItemActionPerformed(evt);
188 }
189 });
190
191 fileMenu.add(saveXsltFileMenuItem);
192 fileMenu.add(jSeparator2);
193 exitMenuItem.setText("Exit");
194 exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
195 public void actionPerformed(java.awt.event.ActionEvent evt) {
196 exitMenuItemActionPerformed(evt);
197 }
198 });
199
200 fileMenu.add(exitMenuItem);
201 menuBar.add(fileMenu);
202 editMenu.setText("Edit");
203 undoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.event.InputEvent.CTRL_MASK));
204 undoMenuItem.setMnemonic('U');
205 undoMenuItem.setText("Undo");
206 undoMenuItem.addActionListener(new java.awt.event.ActionListener() {
207 public void actionPerformed(java.awt.event.ActionEvent evt) {
208 undoMenuItemActionPerformed(evt);
209 }
210 });
211
212 editMenu.add(undoMenuItem);
213 redoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.CTRL_MASK));
214 redoMenuItem.setMnemonic('R');
215 redoMenuItem.setText("Redo");
216 redoMenuItem.addActionListener(new java.awt.event.ActionListener() {
217 public void actionPerformed(java.awt.event.ActionEvent evt) {
218 redoMenuItemActionPerformed(evt);
219 }
220 });
221
222 editMenu.add(redoMenuItem);
223 editMenu.add(jSeparator3);
224 cutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_MASK));
225 cutMenuItem.setText("Cut");
226 cutMenuItem.addActionListener(new java.awt.event.ActionListener() {
227 public void actionPerformed(java.awt.event.ActionEvent evt) {
228 cutMenuItemActionPerformed(evt);
229 }
230 });
231
232 editMenu.add(cutMenuItem);
233 copyMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK));
234 copyMenuItem.setText("Copy");
235 copyMenuItem.addActionListener(new java.awt.event.ActionListener() {
236 public void actionPerformed(java.awt.event.ActionEvent evt) {
237 copyMenuItemActionPerformed(evt);
238 }
239 });
240
241 editMenu.add(copyMenuItem);
242 pasteMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_MASK));
243 pasteMenuItem.setText("Paste");
244 pasteMenuItem.addActionListener(new java.awt.event.ActionListener() {
245 public void actionPerformed(java.awt.event.ActionEvent evt) {
246 pasteMenuItemActionPerformed(evt);
247 }
248 });
249
250 editMenu.add(pasteMenuItem);
251 deleteMenuItem.setText("Delete");
252 deleteMenuItem.addActionListener(new java.awt.event.ActionListener() {
253 public void actionPerformed(java.awt.event.ActionEvent evt) {
254 deleteMenuItemActionPerformed(evt);
255 }
256 });
257
258 editMenu.add(deleteMenuItem);
259 menuBar.add(editMenu);
260 helpMenu.setText("Help");
261 contentsMenuItem.setText("Contents");
262 contentsMenuItem.addActionListener(new java.awt.event.ActionListener() {
263 public void actionPerformed(java.awt.event.ActionEvent evt) {
264 contentsMenuItemActionPerformed(evt);
265 }
266 });
267
268 helpMenu.add(contentsMenuItem);
269 aboutMenuItem.setText("About");
270 aboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
271 public void actionPerformed(java.awt.event.ActionEvent evt) {
272 aboutMenuItemActionPerformed(evt);
273 }
274 });
275
276 helpMenu.add(aboutMenuItem);
277 menuBar.add(helpMenu);
278
279 getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.Y_AXIS));
280
281 setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
282 setTitle(getApplicationName());
283 setIconImage(getIcon("/images/SolarIcon16.gif","Small icon of sun").getImage());
284 addWindowListener(new java.awt.event.WindowAdapter() {
285 public void windowClosing(java.awt.event.WindowEvent evt) {
286 exitForm(evt);
287 }
288 });
289
290 tabbedPane.setPreferredSize(new java.awt.Dimension(640, 500));
291 xmlEditorPane.setPreferredSize(new java.awt.Dimension(106, 400));
292 xmlScrollPane.setViewportView(xmlEditorPane);
293
294 tabbedPane.addTab("jScrollPane4", xmlScrollPane);
295
296 xsltScrollPane.setViewportView(xsltEditorPane);
297
298 tabbedPane.addTab("jScrollPane1", xsltScrollPane);
299
300 resultScrollPane.setViewportView(resultEditorPane);
301
302 tabbedPane.addTab("jScrollPane2", resultScrollPane);
303
304 outputScrollPane.setViewportView(outputEditorPane);
305
306 tabbedPane.addTab("jScrollPane3", outputScrollPane);
307
308 getContentPane().add(tabbedPane);
309
310 controlPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
311
312 controlPanel.setMinimumSize(new java.awt.Dimension(20, 20));
313 controlPanel.setPreferredSize(new java.awt.Dimension(30, 50));
314 transformButton.setMnemonic('T');
315 transformButton.setText("Transform");
316 transformButton.addActionListener(new java.awt.event.ActionListener() {
317 public void actionPerformed(java.awt.event.ActionEvent evt) {
318 transformButtonActionPerformed(evt);
319 }
320 });
321
322 controlPanel.add(transformButton);
323
324 clearButton.setText("Clear");
325 clearButton.addActionListener(new java.awt.event.ActionListener() {
326 public void actionPerformed(java.awt.event.ActionEvent evt) {
327 clearButtonActionPerformed(evt);
328 }
329 });
330
331 controlPanel.add(clearButton);
332
333 getContentPane().add(controlPanel);
334
335 setJMenuBar(menuBar);
336 pack();
337 }//GEN-END:initComponents
338
339 private void redoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_redoMenuItemActionPerformed
340 // Determine which redo to call depending on which tab is selected
341 switch(tabbedPane.getSelectedIndex()) {
342 case 0:
343 xmlRedoAction.actionPerformed(evt);
344 break;
345 case 1:
346 xsltRedoAction.actionPerformed(evt);
347 break;
348 }
349 }//GEN-LAST:event_redoMenuItemActionPerformed
350
351 private void undoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_undoMenuItemActionPerformed
352 // Determine which undo to call depending on which tab is selected
353 switch(tabbedPane.getSelectedIndex()) {
354 case 0:
355 xmlUndoAction.actionPerformed(evt);
356 break;
357 case 1:
358 xsltUndoAction.actionPerformed(evt);
359 break;
360 }
361 }//GEN-LAST:event_undoMenuItemActionPerformed
362
363 private void contentsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_contentsMenuItemActionPerformed
364 // Show help
365 if (helpDialog==null) {
366 helpDialog=new AboutDialog(this,false);
367 Dimension preferredSize=helpDialog.getPreferredSize();
368 Dimension frmSize=getSize();
369 Point loc=getLocation();
370 helpDialog.setLocation((frmSize.width - preferredSize.width) / 2 + loc.x, (frmSize.height - preferredSize.height) + loc.y);
371 StringBuffer helpBuf=new StringBuffer("XSLT Editor ");
372 helpBuf.append(VERSION);
373 helpBuf.append("\n");
374 helpBuf.append("Help is not yet available\n");
375 helpDialog.setAboutText(helpBuf.toString());
376 }
377
378 helpDialog.show();
379 helpDialog.setVisible(true);
380 }//GEN-LAST:event_contentsMenuItemActionPerformed
381
382 private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutMenuItemActionPerformed
383 if (aboutDialog==null) {
384 aboutDialog=new AboutDialog(this,false);
385 Dimension preferredSize=aboutDialog.getPreferredSize();
386 Dimension frmSize=getSize();
387 Point loc=getLocation();
388 aboutDialog.setLocation((frmSize.width - preferredSize.width) / 2 + loc.x, (frmSize.height - preferredSize.height) + loc.y);
389 StringBuffer aboutBuf=new StringBuffer(getApplicationName());
390 aboutBuf.append(VERSION);
391 aboutBuf.append("\n");
392 aboutBuf.append("(c) Copyright Raben Systems Inc., 2002\n");
393 aboutBuf.append("All rights reserved.\n");
394 aboutDialog.setAboutText(aboutBuf.toString());
395 }
396
397 aboutDialog.show();
398 aboutDialog.setVisible(true);
399 }//GEN-LAST:event_aboutMenuItemActionPerformed
400
401 private void deleteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteMenuItemActionPerformed
402 JEditorPane editorPane=getSelectedEditorPane();
403 editorPane.cut();
404 }//GEN-LAST:event_deleteMenuItemActionPerformed
405
406 private void pasteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pasteMenuItemActionPerformed
407 Transferable clipData = clipboard.getContents(clipboard);
408 String selection="";
409 JEditorPane editorPane=getSelectedEditorPane();
410
411 if (clipData != null) {
412 try {
413 selection = (String)(clipData.getTransferData(DataFlavor.stringFlavor));
414 editorPane.replaceSelection(selection);
415 } catch (UnsupportedFlavorException ee) {
416 log("Unsupported flavor: " + ee);
417 } catch (IOException ee) {
418 log("Unable to get data: " + ee);
419 }
420 }
421
422 }//GEN-LAST:event_pasteMenuItemActionPerformed
423
424 private void copyMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyMenuItemActionPerformed
425
426 JEditorPane editorPane=getSelectedEditorPane();
427 String selection=editorPane.getSelectedText();
428 StringSelection data = new StringSelection(selection);
429 clipboard.setContents(data, data);
430
431 }//GEN-LAST:event_copyMenuItemActionPerformed
432
433 /***
434 * Determine edit pane being used and cut text from the pane
435 * @param evt ActionEvent
436 */
437 private void cutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cutMenuItemActionPerformed
438 JEditorPane editorPane=getSelectedEditorPane();
439 String selection=editorPane.getSelectedText();
440 StringSelection data = new StringSelection(selection);
441 clipboard.setContents(data, data);
442 editorPane.cut();
443 }//GEN-LAST:event_cutMenuItemActionPerformed
444
445 /***
446 * Display dialog for entering URL, user name and password.
447 * Registers XsltEditor as a listener, so that when user presses the ok
448 * button the propertyChange method wil open the url and display the xml data
449 * @param evt ActionEvent
450 */
451 private void openXmlUrlMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openXmlUrlMenuItemActionPerformed
452 // First check if xml document has been changed, and ask if user wants
453 // to save it
454 if (xmlUndo.canUndo()) {
455 int result=JOptionPane.showConfirmDialog(this,"XML document has been modified, do you wish to save the changes to a local file?","Save Changes",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
456 if (result==0) {
457 saveXmlMenuItemActionPerformed(null);
458 }
459 }
460
461 // Create dialog to enter URL, user name, and password
462 if (xmlUrlDialog==null) {
463 xmlUrlDialog=new UrlDialog(this,false);
464 xmlUrlDialog.setPropertyName(XML_URL_CHANGED);
465 xmlUrlDialog.addPropertyChangeListener(XML_URL_CHANGED,this);
466 Dimension preferredSize=xmlUrlDialog.getPreferredSize();
467 Dimension frmSize=getSize();
468 Point loc=getLocation();
469 xmlUrlDialog.setLocation((frmSize.width - preferredSize.width) / 2 + loc.x, (frmSize.height - preferredSize.height) / 2 + loc.y);
470
471 }
472
473 xmlUrlDialog.setUrl(lastXmlUrl);
474 xmlUrlDialog.show();
475 xmlUrlDialog.setVisible(true);
476 }//GEN-LAST:event_openXmlUrlMenuItemActionPerformed
477
478 /***
479 * Display dialog for saving contents of xml editor pane to a file
480 * @param evt ActionEvent
481 */
482 private void saveXmlMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveXmlMenuItemActionPerformed
483 JFileChooser chooser = new JFileChooser();
484 ExtensionFileFilter filter = new ExtensionFileFilter();
485 filter.setExtension(".xml");
486 filter.setDescription("XML Files");
487 chooser.setFileFilter(filter);
488
489 if (lastXmlDir!=null) {
490 chooser.setCurrentDirectory(lastXmlDir);
491 }
492 else {
493 if (lastXsltDir!=null) {
494 chooser.setCurrentDirectory(lastXsltDir);
495 }
496 }
497
498 // Display the Save Dialog
499 int returnVal = chooser.showSaveDialog(this);
500 if(returnVal == JFileChooser.APPROVE_OPTION) {
501
502 File xmlFile = chooser.getSelectedFile();
503 String xmlFileName = xmlFile.getAbsolutePath();
504
505
506 try {
507
508 // Get document from xml editor pane
509 org.w3c.dom.Document doc=getDocumentFromEditorPane(xmlEditorPane);
510
511 // Write document to local file system
512 saveDocument(doc,xmlFile);
513
514 // Discard the edits that occurred before file was saved
515 xmlUndo.discardAllEdits();
516
517 // Remember the current directory
518 xmlFileName=xmlFile.getAbsolutePath();
519 int j=xmlFileName.lastIndexOf(File.separator);
520 String dir=xmlFile.getAbsolutePath().substring(0,j);
521 lastXmlDir=new File(dir);
522
523 // Select the xml editor pane to view
524 tabbedPane.setSelectedIndex(0);
525 }
526 catch (IOException e) {
527 log(e.getMessage());
528 tabbedPane.setSelectedIndex(3);
529 }
530 catch (org.xml.sax.SAXException e) {
531 log(e.getMessage());
532 tabbedPane.setSelectedIndex(3);
533 }
534 catch (javax.xml.transform.TransformerException e) {
535 log(e.getMessage());
536 tabbedPane.setSelectedIndex(3);
537 }
538 }
539
540 }//GEN-LAST:event_saveXmlMenuItemActionPerformed
541
542 /***
543 * Display chooser dialog for saving contents of XSLT editor pane to a file
544 * @param evt ActionEvent
545 */
546 private void saveXsltFileMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveXsltFileMenuItemActionPerformed
547 JFileChooser chooser = new JFileChooser();
548 ExtensionFileFilter filter = new ExtensionFileFilter();
549 filter.setExtension(".xsl");
550 filter.setDescription("XSL");
551 chooser.setFileFilter(filter);
552
553 if (lastXmlDir!=null) {
554 chooser.setCurrentDirectory(lastXsltDir);
555 }
556 else {
557 if (lastXsltDir!=null) {
558 chooser.setCurrentDirectory(lastXmlDir);
559 }
560 }
561
562 int returnVal = chooser.showSaveDialog(this);
563 if(returnVal == JFileChooser.APPROVE_OPTION) {
564
565 File xsltFile = chooser.getSelectedFile();
566 String xsltFileName = xsltFile.getAbsolutePath();
567
568
569 try {
570 // Create document from contents of xslt editor pane
571 org.w3c.dom.Document doc=getDocumentFromEditorPane(xsltEditorPane);
572
573 // Write the document to the local file system
574 saveDocument(doc,xsltFile);
575
576 // Discard the edits that occurred before file was saved
577 xsltUndo.discardAllEdits();
578
579 // Remember the current directory
580 int j=xsltFileName.lastIndexOf(File.separator);
581 String dir=xsltFile.getAbsolutePath().substring(0,j);
582 lastXsltDir=new File(dir);
583 tabbedPane.setSelectedIndex(1);
584 }
585 catch (IOException e) {
586 log(e.getMessage());
587 tabbedPane.setSelectedIndex(3);
588 }
589 catch (org.xml.sax.SAXException e) {
590 log(e.getMessage());
591 tabbedPane.setSelectedIndex(3);
592 }
593 catch (javax.xml.transform.TransformerException e) {
594 log(e.getMessage());
595 tabbedPane.setSelectedIndex(3);
596 }
597 }
598
599 }//GEN-LAST:event_saveXsltFileMenuItemActionPerformed
600
601 /***
602 * Display dialog for opening a url and entering username and passsword.
603 * Registers the XsltEditor to listen as a property change listener, so that
604 * when the user presses the ok button, the propertyChange method will open
605 * the url and display the xslt script.
606 * @param evt ActionEvent
607 */
608 private void openXsltUrlMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openXsltUrlMenuItemActionPerformed
609
610 // First check if contents of xslt editor pane has been modified,
611 // if so ask user if they want to save changes
612 if (xsltUndo.canUndo()) {
613 int result=JOptionPane.showConfirmDialog(this,"XSLT document has been modified, do you wish to save the changes to a local file?","Save Changes",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
614 if (result==0) {
615 saveXsltFileMenuItemActionPerformed(null);
616 }
617 }
618
619 // Create instance of UrlDialog and register XsltEditor as propertyChange listener
620 if (xsltUrlDialog==null) {
621 xsltUrlDialog=new UrlDialog(this,false);
622 xsltUrlDialog.setPropertyName(XSLT_URL_CHANGED);
623 xsltUrlDialog.addPropertyChangeListener(XSLT_URL_CHANGED,this);
624 Dimension preferredSize=xsltUrlDialog.getPreferredSize();
625 Dimension frmSize=getSize();
626 Point loc=getLocation();
627 xsltUrlDialog.setLocation((frmSize.width - preferredSize.width) / 2 + loc.x,
628 (frmSize.height - preferredSize.height) / 2 + loc.y);
629 }
630
631 xsltUrlDialog.setUrl(lastXsltUrl);
632 xsltUrlDialog.show();
633 xsltUrlDialog.setVisible(true);
634 }//GEN-LAST:event_openXsltUrlMenuItemActionPerformed
635
636 /***
637 * Clear contents of the selected editor pane
638 * @param evt ActionEvent
639 */
640 private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
641
642 JEditorPane editorPane=getSelectedEditorPane();
643 editorPane.setText("");
644
645 if (tabbedPane.getSelectedIndex()==3) {
646 // clear err messages
647 errBuf=new StringBuffer();
648 }
649 }//GEN-LAST:event_clearButtonActionPerformed
650
651 /***
652 * Transform contents of xml editor pane using the xslt script in the
653 * xslt editor pane, and display in outputEditorPane
654 * @param evt ActionEvent
655 */
656 private void transformButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_transformButtonActionPerformed
657 try {
658 // Read contents of xml editor pane, and create xml document
659 org.w3c.dom.Document inputDoc=getDocumentFromEditorPane(xmlEditorPane);
660 // Read contents of xslt editor pane, and create xslt document
661 org.w3c.dom.Document styleSheetDoc=getDocumentFromEditorPane(xsltEditorPane);
662
663 // Save style sheet as a temporary local file
664 File tempFile=File.createTempFile(".xsl","XsltEditor",lastXsltDir);
665 tempFile.deleteOnExit();
666 saveDocument(styleSheetDoc,tempFile);
667 Templates styleSheet=getStyleSheet(tempFile);
668
669 // Perform the transform
670 outputDoc=transformDocument(inputDoc,styleSheet);
671
672 String str=documentToString(outputDoc);
673
674 if ("html".equals(transformMethod)) {
675 putHtmlInEditorPane(str,resultEditorPane);
676 }
677 else {
678
679 putTextInEditorPane(str,resultEditorPane);
680 }
681
682 tabbedPane.setSelectedIndex(2);
683
684 }
685 catch (org.xml.sax.SAXException e) {
686 log("Error occurred during transform "+e.getMessage());
687 tabbedPane.setSelectedIndex(3);
688 }
689 catch (TransformerException e) {
690 log("Error occurred during transform "+e.getMessage());
691 tabbedPane.setSelectedIndex(3);
692 }
693
694 catch (IOException e) {
695 log("Error occurred during transform "+e.getMessage());
696 tabbedPane.setSelectedIndex(3);
697 }
698
699 }//GEN-LAST:event_transformButtonActionPerformed
700
701 /***
702 * Display a dialog letting user select xslt file from local file system
703 * and then display contents of the file
704 * @param evt ActionEvent
705 */
706 private void openXsltFileMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openXsltFileMenuItemActionPerformed
707 // Check if xslt file has been modified, if so ask user if they
708 // want to save changes
709 if (xsltUndo.canUndo()) {
710 int result=JOptionPane.showConfirmDialog(this,"XSLT document has been modified, do you wish to save the changes to a local file?","Save Changes",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
711 if (result==0) {
712 saveXsltFileMenuItemActionPerformed(null);
713 }
714 }
715
716 JFileChooser chooser = new JFileChooser();
717 ExtensionFileFilter filter = new ExtensionFileFilter();
718 filter.setExtension(".xsl");
719 filter.setDescription("XSLT Files");
720 chooser.setFileFilter(filter);
721
722 if (lastXsltDir!=null) {
723 chooser.setCurrentDirectory(lastXsltDir);
724 }
725 else {
726 if (lastXmlDir!=null) {
727 chooser.setCurrentDirectory(lastXmlDir);
728 }
729 }
730
731 int returnVal = chooser.showOpenDialog(this);
732
733 if(returnVal == JFileChooser.APPROVE_OPTION) {
734 File xsltFile= chooser.getSelectedFile();
735 String xsltFileName = xsltFile.getAbsolutePath();
736 xsltEditorPane.setText("");
737
738 try {
739 org.w3c.dom.Document xsltDoc=documentBuilder.parse(xsltFile);
740 log("Opened XSLT file "+xsltFileName);
741
742 // Convert the xml document to string for display
743 xsltEditorPane.setText(nodeToString(xsltDoc,""));
744
745 // Remember the current directory for next time
746 int j=xsltFileName.lastIndexOf(File.separator);
747 String dir=xsltFile.getAbsolutePath().substring(0,j);
748 lastXsltDir=new File(dir);
749 xsltUndo.discardAllEdits();
750 saveProps();
751
752 // Set view to xslt editor pane
753 tabbedPane.setSelectedIndex(1);
754 }
755 catch (org.xml.sax.SAXException e) {
756 log("Error occurred parsing file "+e.getMessage());
757 }
758 catch (IOException e) {
759 log(e.getMessage());
760 tabbedPane.setSelectedIndex(3);
761 }
762
763 xsltFile=null;
764
765 }
766 }//GEN-LAST:event_openXsltFileMenuItemActionPerformed
767
768 /***
769 * Create dialog for selecting an XML file and then display the contents in
770 * an editor pane
771 * @param evt ActionEvent
772 */
773 private void openXmlFileMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openXmlFileMenuItemActionPerformed
774 // First check if xml document has been changed, and ask if user wants
775 // to save it
776 if (xmlUndo.canUndo()) {
777 int result=JOptionPane.showConfirmDialog(this,"XML document has been modified, do you wish to save the changes to a local file?","Save Changes",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
778 if (result==0) {
779 saveXmlMenuItemActionPerformed(null);
780 }
781 }
782
783 // Create file chooser dialog
784 JFileChooser chooser = new JFileChooser();
785
786 // Create filter so only xml files are shown in file chooser
787 ExtensionFileFilter filter = new ExtensionFileFilter();
788 filter.setExtension(".xml");
789 filter.setDescription("XML Files");
790 chooser.setFileFilter(filter);
791
792 // Set default directory to that previously used when xml or xslt file opened
793 if (lastXmlDir!=null) {
794 chooser.setCurrentDirectory(lastXmlDir);
795 }
796 else {
797 if (lastXsltDir!=null) {
798 chooser.setCurrentDirectory(lastXsltDir);
799 }
800 }
801
802 // Display the file chooser dialog
803 int returnVal = chooser.showOpenDialog(this);
804
805 // Open the selected file
806 if(returnVal == JFileChooser.APPROVE_OPTION) {
807 log("Opened XML file: " +chooser.getSelectedFile().getName());
808
809 // open the selected xml file
810 File xmlFile = chooser.getSelectedFile();
811
812 try {
813 xmlEditorPane.setText("");
814
815 // Parse the xml file
816 inputDoc=documentBuilder.parse(xmlFile);
817
818 // Convert the xml document to string for display
819 xmlEditorPane.setText(nodeToString(inputDoc,""));
820
821 //xmlEditorPane.setText(nodeToString(inputDoc,""));
822 xmlUndo.discardAllEdits();
823 tabbedPane.setSelectedIndex(0);
824
825 // Remember what directory we're in for next time
826 String xmlFileName=xmlFile.getAbsolutePath();
827 int j=xmlFileName.lastIndexOf(File.separator);
828 String dir=xmlFile.getAbsolutePath().substring(0,j);
829 lastXmlDir=new File(dir);
830 saveProps();
831 }
832 catch (IOException e) {
833 log(e.getMessage());
834 tabbedPane.setSelectedIndex(3);
835 }
836 catch (org.xml.sax.SAXException e) {
837 log(e.getMessage());
838 tabbedPane.setSelectedIndex(3);
839 }
840
841
842 }
843
844 }//GEN-LAST:event_openXmlFileMenuItemActionPerformed
845
846 /***
847 * User has selected exit from the file menu
848 * @param evt ActionEvent
849 */
850 private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
851 exitForm(null);
852 }//GEN-LAST:event_exitMenuItemActionPerformed
853
854 /*** Check if editor contents have been
855 * modified, if so ask user if they want to save changes, and then
856 * exit the application
857 * @param evt WindowEvent
858 */
859 private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
860 if (xmlUndo.canUndo()) {
861 int result=JOptionPane.showConfirmDialog(this,"XML document has been modified, do you wish to save the changes to a local file?","Save Changes",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
862 if (result==0) {
863 saveXmlMenuItemActionPerformed(null);
864 }
865 }
866
867 if (xsltUndo.canUndo()) {
868 int result=JOptionPane.showConfirmDialog(this,"XSLT document has been modified, do you wish to save the changes to a local file?","Save Changes",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
869 if (result==0) {
870 saveXsltFileMenuItemActionPerformed(null);
871 }
872 }
873
874 System.exit(0);
875 }//GEN-LAST:event_exitForm
876
877 /***
878 * @param args the command line arguments
879 */
880 public static void main(String args[]) {
881 new XsltEditor().show();
882 }
883
884 /***
885 * Load xslt text from xslt editor pane, convert to dom source,
886 * and return style sheet
887 * @return Templates XSL stylesheet
888 * @throws IOException if there is a problem loading xsl file from file system
889 * @throws TransformerConfigurationException if there is a problem with configuration (check classpath)
890 * @throws SAXException if there is a problem parsing the XSLT
891 */
892 private Templates getStyleSheet(File fil) throws IOException, TransformerConfigurationException,SAXException {;
893 StreamSource streamSource=new StreamSource(fil);
894 TransformerFactory factory=TransformerFactory.newInstance();
895 return factory.newTemplates(streamSource);
896 }
897
898 /***
899 * Append message to an StringBuffer and then display text in log pane
900 * @param msg String Message to be appended to log
901 */
902 private void log(java.lang.String msg) {
903 errBuf.append(msg);
904 errBuf.append("\n");
905 outputEditorPane.setText(errBuf.toString());
906 }
907
908 /***
909 * Transform xml document using a stylesheet template
910 * @param doc Document DOM document to be transformed
911 * @param styleSheet Templates Style sheet template specifying the transform
912 * @throws IOException if one of the parameters is null or if there is an error
913 * in the configuration or style sheet
914 */
915 private org.w3c.dom.Document transformDocument( org.w3c.dom.Document doc,
916 Templates styleSheet) throws IOException {
917 org.w3c.dom.Document retDoc=null;
918
919 try {
920 DOMSource domSource = new DOMSource(doc);
921 DOMResult domResult = new DOMResult();
922
923 // Perform the transformation, placing the output in the DOMResult.
924 Transformer transformer=styleSheet.newTransformer();
925 transformer.transform(domSource, domResult);
926 transformMethod=transformer.getOutputProperties().getProperty("method");
927 retDoc=(org.w3c.dom.Document)domResult.getNode();
928 domSource=null;
929 domResult=null;
930 transformer=null;
931 }
932
933 catch (TransformerConfigurationException e) {
934 log("Error loading transformer stylesheet "+e.getMessage());
935 throw new IOException("transformDocument:"+e.getMessage());
936 }
937 catch (TransformerException e) {
938 log("Error performing transformation "+e.getMessage());
939 throw new IOException("tranformDocument:"+e.getMessage());
940 }
941 catch (NullPointerException e) {
942 log("Error occurred, document was null");
943 throw new IOException(e.getMessage());
944 }
945
946 return retDoc;
947
948 }
949
950 /***
951 * Initialize tabbed pane titles
952 */
953 private void initTabbedPane() {
954 String[] tabNames={"XML File","XSLT File","Result","Output Log"};
955
956 for (int i=0;i<tabbedPane.getComponentCount();i++) {
957 tabbedPane.setTitleAt(i,tabNames[i]);
958 }
959
960 }
961
962
963 /***
964 * Handle property change events from UrlDialog and LicenseDialog
965 * When user presses OK button on URL dialog the
966 * specified URL is opened, an authenticator for entering username and
967 * password is set, the xmls or xslt file is downloaded and displayed
968 * in the appropriate editor pane.
969 * When user presses Accept button on license dialog, a flag is set and then
970 * stored in a configuration file, if the user declines the license, the
971 * application exits.
972 * @param propertyChangeEvent PropertyChangeEvent
973 */
974 public void propertyChange(java.beans.PropertyChangeEvent propertyChangeEvent) {
975 String propName=propertyChangeEvent.getPropertyName();
976 String urlStr=(String)propertyChangeEvent.getNewValue();
977
978 if (XML_URL_CHANGED.equals(propName)) {
979 try {
980 // Set authenticator for the XML URL
981 Authenticator.setDefault(new XmlUrlAuthenticator());
982 URL url = new URL(urlStr);
983
984 // Open the url connection
985 URLConnection urlConnection = url.openConnection();
986 InputStream is = urlConnection.getInputStream();
987 BufferedReader br = new BufferedReader(new InputStreamReader(is));
988
989 // Read data from connection
990 if (br.ready()) {
991 InputSource inputSource=new InputSource(br);
992 inputDoc=documentBuilder.parse(inputSource);
993
994 // Convert the xml document to string for display
995 xmlEditorPane.setText(nodeToString(inputDoc,""));
996
997 inputSource=null;
998 tabbedPane.setSelectedIndex(0);
999 xmlUndo.discardAllEdits();
1000 br.close();
1001 log("Retrieved URL "+urlStr);
1002
1003 // Remember the url used for next time
1004 lastXmlUrl=urlStr;
1005 saveProps();
1006 }
1007 else {
1008 log("Error cannot read url "+urlStr);
1009 tabbedPane.setSelectedIndex(3);
1010 }
1011
1012
1013 is.close();
1014 br=null;
1015 is=null;
1016 urlConnection=null;
1017 url=null;
1018 }
1019 catch (IOException e) {
1020 log("Error cannot open url "+urlStr+" ("+e.getMessage()+")");
1021 tabbedPane.setSelectedIndex(3);
1022 }
1023 catch (org.xml.sax.SAXException e) {
1024 log(e.getMessage());
1025 tabbedPane.setSelectedIndex(3);
1026 }
1027
1028 }
1029 else if (XSLT_URL_CHANGED.equals(propName)) {
1030
1031 try {
1032
1033 // Set authenticator for the XSLT URL
1034 Authenticator.setDefault(new XsltUrlAuthenticator());
1035 URL url = new URL(urlStr);
1036 URLConnection urlConnection = url.openConnection();
1037 InputStream is = urlConnection.getInputStream();
1038 BufferedReader br = new BufferedReader(new InputStreamReader(is));
1039
1040 // Read data from the URL
1041 if (br.ready()) {
1042 InputSource inputSource=new InputSource(br);
1043 org.w3c.dom.Document xsltDoc=documentBuilder.parse(inputSource);
1044
1045 // Convert the xml document to string for display
1046 xsltEditorPane.setText(nodeToString(xsltDoc,""));
1047 tabbedPane.setSelectedIndex(1);
1048
1049 inputSource=null;
1050 xsltUndo.discardAllEdits();
1051 br.close();
1052 log("Retrieved URL "+urlStr);
1053 lastXsltUrl=urlStr;
1054 saveProps();
1055 }
1056 else {
1057 log("Error cannot read url "+urlStr);
1058 tabbedPane.setSelectedIndex(3);
1059 }
1060
1061
1062 is.close();
1063 br=null;
1064 is=null;
1065 urlConnection=null;
1066 url=null;
1067 }
1068 catch (IOException e) {
1069 log("Error reading url "+urlStr+" ("+e.getMessage()+")");
1070 tabbedPane.setSelectedIndex(3);
1071 }
1072 catch (org.xml.sax.SAXException e) {
1073 log(e.getMessage());
1074 tabbedPane.setSelectedIndex(3);
1075 }
1076 }
1077 else if (LicenseDialog.LICENSE_RESPONSE.equals(propName)) {
1078 if ("true".equals(urlStr)) {
1079 licenseAccepted="yes";
1080 saveProps();
1081 return;
1082 }
1083 else {
1084 exitForm(null);
1085 }
1086 }
1087 else {
1088 log("propName not recognized: "+propName);
1089 tabbedPane.setSelectedIndex(3);
1090 }
1091
1092 }
1093
1094
1095 private JEditorPane getSelectedEditorPane() {
1096 JEditorPane editorPane=outputEditorPane;
1097
1098 switch(tabbedPane.getSelectedIndex()) {
1099 case 0:
1100 editorPane=xmlEditorPane;
1101 break;
1102 case 1:
1103 editorPane=xsltEditorPane;
1104 break;
1105 case 2:
1106 editorPane=resultEditorPane;
1107 break;
1108 case 3:
1109 editorPane=outputEditorPane;
1110 break;
1111 }
1112
1113 return editorPane;
1114 }
1115
1116 /***
1117 * Save the document to a file
1118 * @param doc Document the document to be saved
1119 * @param fil File The file to write to
1120 * @throws TransformerException For errors in document or configuration of the transformer
1121 */
1122 public void saveDocument(org.w3c.dom.Document doc, File fil) throws TransformerException {
1123
1124 // Create dom source for the document
1125 DOMSource domSource=new DOMSource(doc);
1126
1127 // Create the result stream for the transform
1128 StreamResult result = new StreamResult(fil);
1129
1130 // Use a Transformer for output
1131 TransformerFactory tFactory =TransformerFactory.newInstance();
1132 Transformer transformer = tFactory.newTransformer();
1133 transformer.setOutputProperty("indent","yes");
1134 // transform the document to the result stream
1135 transformer.transform(domSource, result);
1136 log("Saved document "+doc.getDocumentElement().getTagName()+" in file "+fil.getAbsolutePath());
1137 }
1138
1139 public void saveProps() {
1140 Properties props=new Properties();
1141 if ((lastXmlDir!=null)&&(lastXmlDir.exists())) {
1142 props.setProperty("lastXmlDir",lastXmlDir.getAbsolutePath());
1143 }
1144
1145 if ((lastXsltDir!=null)&&(lastXsltDir.exists())) {
1146 props.setProperty("lastXsltDir",lastXsltDir.getAbsolutePath());
1147 }
1148
1149 if ((lastXmlUrl!=null)&&(lastXmlUrl.length()>0)) {
1150 props.setProperty("lastXmlUrl",lastXmlUrl);
1151 }
1152
1153 if ((lastXsltUrl!=null)&&(lastXsltUrl.length()>0)) {
1154 props.setProperty("lastXsltUrl",lastXsltUrl);
1155 }
1156
1157 if ((licenseAccepted!=null)&&(licenseAccepted.length()>0)) {
1158 props.setProperty("licenseAccepted",licenseAccepted);
1159 }
1160
1161 String propFileName=System.getProperties().getProperty("user.home")+File.separator+getApplicationName()+".properties";
1162 try {
1163 FileOutputStream fos=new FileOutputStream(propFileName);
1164 props.store(fos,getApplicationName());
1165 fos.close();
1166 fos=null;
1167 }
1168 catch (IOException e) {
1169 log("Error unable to save preferences to "+propFileName+" error="+e.getMessage());
1170 tabbedPane.setSelectedIndex(3);
1171 }
1172 }
1173
1174 /***
1175 * Load properties from local file system
1176 */
1177 public void loadProps() {
1178 Properties props=new Properties();
1179 String propFileName=System.getProperties().getProperty("user.home")+File.separator+getApplicationName()+".properties";
1180 try {
1181 FileInputStream fis=new FileInputStream(propFileName);
1182 log("Load preferences from "+propFileName);
1183 props.load(fis);
1184 fis.close();
1185 String xmlDirStr=props.getProperty("lastXmlDir");
1186
1187 if ((xmlDirStr!=null)&&(xmlDirStr.length()>0)) {
1188 lastXmlDir=new File(xmlDirStr);
1189 }
1190
1191 String xsltDirStr=props.getProperty("lastXsltDir");
1192
1193 if ((xsltDirStr!=null)&&(xsltDirStr.length()>0)) {
1194 lastXsltDir=new File(xsltDirStr);
1195 }
1196
1197 lastXmlUrl=props.getProperty("lastXmlUrl");
1198 lastXsltUrl=props.getProperty("lastXsltUrl");
1199 licenseAccepted=props.getProperty("licenseAccepted","no");
1200 }
1201 catch (IOException e) {} // ignore as there may not be a preference file the first time
1202 }
1203
1204 /***
1205 * Retrieve contents of editor pane, parse it, and return as a DOM document
1206 * @param editorPane JEditorPane the selected editor pane
1207 * @throws SAXException if there is an error parsing the document
1208 * @throws IOException if there is a problem reading the text
1209 */
1210 private org.w3c.dom.Document getDocumentFromEditorPane(JEditorPane editorPane) throws SAXException,IOException {
1211 StringReader reader=new StringReader(editorPane.getText());
1212 InputSource inputSource=new InputSource(reader);
1213 return documentBuilder.parse(inputSource);
1214 }
1215
1216 private Action getActionByName(String name) {
1217 return (Action)(actions.get(name));
1218 }
1219
1220 /***
1221 * Display a dialog showing license to use software, register XsltEditor as
1222 * a propertyChange listener that handles property change events that occur
1223 * when user presses accept or decline buttons.
1224 */
1225 private void showLicenseDialog() {
1226 LicenseDialog licenseDialog=new LicenseDialog(this,false);
1227 licenseDialog.addPropertyChangeListener(LicenseDialog.LICENSE_RESPONSE,this);
1228 Dimension preferredSize=licenseDialog.getPreferredSize();
1229 Dimension frmSize=getSize();
1230 Point loc=getLocation();
1231 licenseDialog.setLocation((frmSize.width - preferredSize.width) / 2 + loc.x, (frmSize.height - preferredSize.height) + loc.y);
1232 licenseDialog.show();
1233 licenseDialog.setVisible(true);
1234 }
1235
1236 /***
1237 * Load an icon from jar file
1238 */
1239 private ImageIcon getIcon(java.lang.String iconName, String description) {
1240 URL url=getClass().getResource(iconName);
1241 ImageIcon icon=null;
1242 if (url!=null) {
1243 icon=new ImageIcon(url);
1244 }
1245
1246 if (icon==null) {
1247 icon=EMPTY_ICON16;
1248 System.out.println("getIcon unable to load iconName="+iconName);
1249 }
1250
1251 icon.setDescription(description);
1252
1253 return icon;
1254
1255 }
1256
1257
1258
1259 /***
1260 * Convert document to string for display
1261 * @param doc org.w3c.dom.Document
1262 */
1263 private String documentToString(org.w3c.dom.Document doc) throws TransformerException {
1264
1265 // Create dom source for the document
1266 DOMSource domSource=new DOMSource(doc);
1267
1268 // Create string writer
1269 StringWriter stringWriter=new StringWriter();
1270
1271 // Create the result stream for the transform
1272 StreamResult result = new StreamResult(stringWriter);
1273
1274 // Use a Transformer for output
1275 TransformerFactory tFactory =TransformerFactory.newInstance();
1276 Transformer transformer = tFactory.newTransformer();
1277 transformer.setOutputProperty("indent","yes");
1278
1279 // Transform the document to the result stream
1280 transformer.transform(domSource, result);
1281 return stringWriter.toString();
1282 }
1283
1284
1285 /***
1286 * Undo edit listener for XML Editor pane
1287 */
1288 class XmlUndoableEditListener implements UndoableEditListener {
1289 public void undoableEditHappened(UndoableEditEvent e) {
1290 //Remember the edit and update the menus
1291 xmlUndo.addEdit(e.getEdit());
1292 xmlUndoAction.updateUndoState();
1293 xmlRedoAction.updateRedoState();
1294 }
1295 }
1296
1297 /***
1298 * Redo Actions for XSLT editor pane
1299 */
1300 class XsltRedoAction extends AbstractAction {
1301 public XsltRedoAction() {
1302 super("Redo");
1303 setEnabled(false);
1304 }
1305
1306 public void actionPerformed(ActionEvent e) {
1307 try {
1308 xsltUndo.redo();
1309 } catch (CannotRedoException ex) {
1310 log("Unable to redo: " + ex);
1311 xsltEditor.getToolkit().beep();
1312 //ex.printStackTrace();
1313 }
1314 updateRedoState();
1315 xsltUndoAction.updateUndoState();
1316 }
1317
1318 protected void updateRedoState() {
1319 if (xsltUndo.canRedo()) {
1320 setEnabled(true);
1321 putValue(Action.NAME, xsltUndo.getRedoPresentationName());
1322 } else {
1323 setEnabled(false);
1324 putValue(Action.NAME, "Redo");
1325 }
1326 }
1327
1328 }
1329
1330 private void putHtmlInEditorPane(String html,JEditorPane editorPane) {
1331 editorPane.setContentType("text/html");
1332 editorPane.setText("");
1333 EditorKit kit=editorPane.getEditorKitForContentType("text/html");
1334 javax.swing.text.Document doc = editorPane.getDocument();
1335 StringReader reader = new StringReader(html);
1336 try {
1337 kit.read(reader, doc, 0);
1338 }
1339 catch (IOException e){}
1340 catch (BadLocationException e){}
1341 }
1342
1343 private void putTextInEditorPane(String txt, JEditorPane editorPane) {
1344 editorPane.setContentType("text/plain");
1345 editorPane.setText(txt);
1346 }
1347
1348 public String getApplicationName() {
1349 return applicationName;
1350 }
1351
1352 /***
1353 * Return string representation of an element
1354 * @return java.lang.String
1355 * @param elem org.w3c.dom.Element
1356 */
1357 private String nodeToString(Node node,String indent) {
1358
1359 if (node == null) {
1360 return "";
1361 }
1362
1363 StringBuffer buf=new StringBuffer();
1364 int type = node.getNodeType();
1365
1366 switch (type) {
1367 case Node.DOCUMENT_NODE : {
1368 buf.append("<?xml version=\"1.0\"?>\n");
1369
1370 NodeList children = node.getChildNodes();
1371
1372 if (children != null)
1373 {
1374 int numChildren = children.getLength();
1375
1376 for (int i = 0; i < numChildren; i++)
1377 {
1378 buf.append(nodeToString(children.item(i),""));
1379 }
1380 }
1381 break;
1382
1383 }
1384
1385 case Node.ELEMENT_NODE : {
1386 buf.append(indent);
1387 buf.append('<' + node.getNodeName());
1388
1389 NamedNodeMap attrs = node.getAttributes();
1390 int len = (attrs != null) ? attrs.getLength() : 0;
1391
1392 for (int i = 0; i < len; i++) {
1393 Attr attr = (Attr)attrs.item(i);
1394
1395 buf.append(' ' + attr.getNodeName() +"=\"" +
1396 attr.getNodeValue() + '\"');
1397 }
1398
1399 buf.append(">");
1400
1401 NodeList children = node.getChildNodes();
1402
1403 if (children != null) {
1404 int numChildren = children.getLength();
1405
1406 for (int i = 0; i < numChildren; i++) {
1407 if (children.item(i).getNodeType()==Node.TEXT_NODE) {
1408 buf.append(nodeToString(children.item(i),""));
1409 }
1410 else {
1411 buf.append("\n");
1412 buf.append(nodeToString(children.item(i),indent+" "));
1413 buf.append(indent);
1414 }
1415 }
1416 }
1417
1418 buf.append("</");
1419 buf.append(node.getNodeName());
1420 buf.append(">\n");
1421 break;
1422 }
1423
1424 case Node.ENTITY_REFERENCE_NODE : {
1425 buf.append('&');
1426 buf.append(node.getNodeName());
1427 buf.append(';');
1428 break;
1429 }
1430
1431 case Node.CDATA_SECTION_NODE : {
1432 buf.append("\n");
1433 buf.append(indent);
1434 buf.append("<![CDATA[");
1435 buf.append(node.getNodeValue());
1436 buf.append("]]>\n");
1437 break;
1438 }
1439
1440 case Node.TEXT_NODE : {
1441 buf.append(node.getNodeValue());
1442 break;
1443 }
1444
1445 case Node.COMMENT_NODE : {
1446 buf.append("\n");
1447 buf.append(indent);
1448 buf.append("<!--");
1449 buf.append(node.getNodeValue());
1450 buf.append("-->\n");
1451 break;
1452 }
1453
1454 case Node.PROCESSING_INSTRUCTION_NODE : {
1455 buf.append("<?");
1456 buf.append(node.getNodeName());
1457
1458 String data = node.getNodeValue();
1459
1460 if (data != null && data.length() > 0) {
1461 buf.append(' ');
1462 buf.append(data);
1463 }
1464
1465 buf.append("?>\n");
1466 break;
1467 }
1468
1469 case Node.DOCUMENT_TYPE_NODE: {
1470 log("document type node not handled");
1471 break;
1472 }
1473 default: {
1474 log("type="+type+" not recognized");
1475 break;
1476 }
1477
1478 }
1479
1480 return buf.toString();
1481
1482 }
1483
1484 /***
1485 * Undo actions for XSLT editor pane
1486 */
1487 class XsltUndoAction extends AbstractAction {
1488 public XsltUndoAction() {
1489 super("Undo");
1490 setEnabled(false);
1491 }
1492
1493 public void actionPerformed(ActionEvent e) {
1494 try {
1495 xsltUndo.undo();
1496 } catch (CannotUndoException ex) {
1497 log("Unable to undo: " + ex);
1498 xsltEditor.getToolkit().beep();
1499 //ex.printStackTrace();
1500 }
1501 updateUndoState();
1502 xsltRedoAction.updateRedoState();
1503 }
1504
1505 protected void updateUndoState() {
1506 if (xsltUndo.canUndo()) {
1507 setEnabled(true);
1508 putValue(Action.NAME, xsltUndo.getUndoPresentationName());
1509 } else {
1510 setEnabled(false);
1511 putValue(Action.NAME, "Undo");
1512 }
1513 }
1514
1515
1516 }
1517 /***
1518 * Undo Edit listener for XSLT editor pane
1519 */
1520 class XsltUndoableEditListener implements UndoableEditListener {
1521 public void undoableEditHappened(UndoableEditEvent e) {
1522 //Remember the edit and update the menus
1523 xsltUndo.addEdit(e.getEdit());
1524 xsltUndoAction.updateUndoState();
1525 xsltRedoAction.updateRedoState();
1526 }
1527 }
1528
1529 /***
1530 * Filter which files FileChooser will show
1531 */
1532 class ExtensionFileFilter extends javax.swing.filechooser.FileFilter {
1533 private String ext=".txt";
1534 private String description="";
1535
1536 public void setExtension(String ext) {
1537 this.ext=ext;
1538 }
1539
1540 public void setDescription(String description) {
1541 this.description=description;
1542 }
1543
1544 public boolean accept(java.io.File file) {
1545 if(file.isDirectory()) {
1546 return true;
1547 }
1548 else {
1549 return file.getName().endsWith(ext);
1550 }
1551 }
1552
1553 public java.lang.String getDescription() {
1554 return description;
1555 }
1556
1557 }
1558 /***
1559 * Redo actions for XML Editor pane
1560 */
1561 class XmlRedoAction extends AbstractAction {
1562 public XmlRedoAction() {
1563 super("Redo");
1564 setEnabled(false);
1565 }
1566
1567 public void actionPerformed(ActionEvent e) {
1568 try {
1569 xmlUndo.redo();
1570 } catch (CannotRedoException ex) {
1571 log("Unable to redo: " + ex);
1572
1573 xsltEditor.getToolkit().beep();
1574 //ex.printStackTrace();
1575 }
1576 updateRedoState();
1577 xmlUndoAction.updateUndoState();
1578 }
1579
1580 protected void updateRedoState() {
1581 if (xmlUndo.canRedo()) {
1582 setEnabled(true);
1583 putValue(Action.NAME, xmlUndo.getRedoPresentationName());
1584 } else {
1585 setEnabled(false);
1586 putValue(Action.NAME, "Redo");
1587 }
1588 }
1589
1590 }
1591
1592 /***
1593 * Undo actions for XML Editor pane
1594 */
1595 class XmlUndoAction extends AbstractAction {
1596 public XmlUndoAction() {
1597 super("Undo");
1598 setEnabled(false);
1599 }
1600
1601
1602 public void actionPerformed(ActionEvent e) {
1603 try {
1604 xmlUndo.undo();
1605 } catch (CannotUndoException ex) {
1606 log("Unable to undo: " + ex);
1607 xsltEditor.getToolkit().beep();
1608 //ex.printStackTrace();
1609 }
1610 updateUndoState();
1611 xmlRedoAction.updateRedoState();
1612 }
1613
1614 protected void updateUndoState() {
1615 if (xmlUndo.canUndo()) {
1616 setEnabled(true);
1617 putValue(Action.NAME, xmlUndo.getUndoPresentationName());
1618 } else {
1619 setEnabled(false);
1620 putValue(Action.NAME, "Undo");
1621 }
1622 }
1623
1624
1625 }
1626
1627 /***
1628 * Authenticator for the XML URL
1629 */
1630 class XmlUrlAuthenticator extends java.net.Authenticator {
1631 protected java.net.PasswordAuthentication getPasswordAuthentication() {
1632 return xmlUrlDialog.getAuthentication();
1633 }
1634 }
1635
1636
1637 /***
1638 * Authenticator for the XSLT URL
1639 */
1640 class XsltUrlAuthenticator extends java.net.Authenticator {
1641 protected java.net.PasswordAuthentication getPasswordAuthentication() {
1642 return xsltUrlDialog.getAuthentication();
1643 }
1644 }
1645
1646
1647 private final static String VERSION="1.5";
1648 private File lastXsltDir;
1649 private File lastXmlDir;
1650 private String lastXmlUrl="http://www.spaceweather.info/swData/servlet1?dataSet=activeRegion";
1651 private String lastXsltUrl="";
1652 private TreeMap styleSheetMap=new TreeMap();
1653 private TreeMap styleSheetLastModifiedMap=new TreeMap();
1654 private StringBuffer errBuf=new StringBuffer();
1655 private org.w3c.dom.Document inputDoc;
1656 private org.w3c.dom.Document outputDoc;
1657 private DocumentBuilder documentBuilder;
1658 private DocumentBuilderFactory documentBuilderFactory;
1659 private UrlDialog xmlUrlDialog;
1660 private UrlDialog xsltUrlDialog;
1661 private AboutDialog aboutDialog;
1662 private AboutDialog helpDialog;
1663 private static final String XML_URL_CHANGED="XML_URL_CHANGED";
1664 private static final String XSLT_URL_CHANGED="XSLT_URL_CHANGED";
1665 private static final String ACCEPT_LICENSE="ACCEPT_LICENSE";
1666 private final Clipboard clipboard =Toolkit.getDefaultToolkit().getSystemClipboard();
1667 private static ImageIcon EMPTY_ICON16 = new ImageIcon(new BufferedImage(16,16,BufferedImage.TYPE_INT_RGB));
1668 private String licenseAccepted="no";
1669 private XsltEditor xsltEditor;
1670
1671 // The following support undo/redo
1672 private UndoManager xmlUndo=new UndoManager();
1673 private UndoManager xsltUndo=new UndoManager();
1674 private XmlUndoAction xmlUndoAction;
1675 private XmlRedoAction xmlRedoAction;
1676 private XsltRedoAction xsltRedoAction;
1677 private XsltUndoAction xsltUndoAction;
1678 private Hashtable actions;
1679 /*** Set by transformer so editor knows media-type generated */
1680 private String transformMethod="xml";
1681
1682
1683 // Variables declaration - do not modify//GEN-BEGIN:variables
1684 private javax.swing.JMenuBar menuBar;
1685 private javax.swing.JMenu fileMenu;
1686 private javax.swing.JMenuItem openXmlFileMenuItem;
1687 private javax.swing.JMenuItem openXmlUrlMenuItem;
1688 private javax.swing.JMenuItem saveXmlMenuItem;
1689 private javax.swing.JSeparator jSeparator1;
1690 private javax.swing.JMenuItem openXsltFileMenuItem;
1691 private javax.swing.JMenuItem openXsltUrlMenuItem;
1692 private javax.swing.JMenuItem saveXsltFileMenuItem;
1693 private javax.swing.JSeparator jSeparator2;
1694 private javax.swing.JMenuItem exitMenuItem;
1695 private javax.swing.JMenu editMenu;
1696 private javax.swing.JMenuItem undoMenuItem;
1697 private javax.swing.JMenuItem redoMenuItem;
1698 private javax.swing.JSeparator jSeparator3;
1699 private javax.swing.JMenuItem cutMenuItem;
1700 private javax.swing.JMenuItem copyMenuItem;
1701 private javax.swing.JMenuItem pasteMenuItem;
1702 private javax.swing.JMenuItem deleteMenuItem;
1703 private javax.swing.JMenu helpMenu;
1704 private javax.swing.JMenuItem contentsMenuItem;
1705 private javax.swing.JMenuItem aboutMenuItem;
1706 private javax.swing.JTabbedPane tabbedPane;
1707 private javax.swing.JScrollPane xmlScrollPane;
1708 private javax.swing.JEditorPane xmlEditorPane;
1709 private javax.swing.JScrollPane xsltScrollPane;
1710 private javax.swing.JEditorPane xsltEditorPane;
1711 private javax.swing.JScrollPane resultScrollPane;
1712 private javax.swing.JEditorPane resultEditorPane;
1713 private javax.swing.JScrollPane outputScrollPane;
1714 private javax.swing.JEditorPane outputEditorPane;
1715 private javax.swing.JPanel controlPanel;
1716 private javax.swing.JButton transformButton;
1717 private javax.swing.JButton clearButton;
1718 // End of variables declaration//GEN-END:variables
1719
1720 public String applicationName = "XsltEditor";
1721
1722 }
This page was automatically generated by Maven