/* Copyright (c) 2000 by INRIA. Read the COPYRIGHT file. */ /* Author: Claude.Pasquier@sophia.inria.fr */ package fr.inria.ketuk; import javax.swing.*; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import java.util.*; import org.w3c.dom.*; import org.apache.xml.serialize.*; import org.xml.sax.*; /** * Implementation of a basic application * allowing the edition of a XML document with it's associated * XSLT file *

* This implementation if more perfectionned that XEdit with the * possibility to visualize source XML document and generated beans, * to reload both XSLT script and XML document and to save in a file * the modified xml document * * @author Claude Pasquier */ public final class BeansEdit extends JApplet implements XEditListener, ActionListener, ItemListener { private static Vector editorList = new Vector(); private Document xmlSourceDoc = null; private Document xslSourceDoc = null; private Document sklSourceDoc = null; private URL xmlSourceUrl = null; private URL sklSourceUrl = null; private URL xslSourceUrl = null; private String xmlSource = null; private XBMapper xbm = null; private JTextArea sourceComp = null; private JSplitPane splitPane = null; private JScrollPane sourceView = null; private JScrollPane resultBeansView = null; private int dividerLocation = 300; // menus private JMenuItem loadXMLMenu = null; private JMenuItem loadXSLMenu = null; private JMenuItem saveXMLMenu = null; private JMenuItem saveXMLAsMenu = null; private JMenuItem quitAndSaveMenu = null; private JMenuItem quitAndDiscardMenu= null; private JMenuItem newViewMenu = null; private JCheckBoxMenuItem viewSourceMenu = null; // private static DOMTreeFull domTree = null; private boolean sourceVisible = false; /** * Entry point of the class. *

* Processes xml ans xslt documents, generates the corresponding bean * hierarchy and displays it **/ public static void main(String[] args) { JFrame frame = new JFrame (); BeansEdit applet = new BeansEdit(); // initialize xml, xsl and skl sources applet.parseArgs(args); editorList.addElement(applet); applet.init(); frame.getContentPane().add("Center", applet); frame.setSize(1000, 600); frame.addWindowListener (new WindowAdapter () { public void windowClosing (WindowEvent e) { System.exit (0); }}); applet.start(); frame.setVisible(true); } /** * Default constructor */ BeansEdit() { } /** * Constructor */ BeansEdit(Document xmlDoc, Document xslDoc, Document sklDoc, URL xmlUrl) { xmlSourceDoc = xmlDoc; xslSourceDoc = xslDoc; sklSourceDoc = sklDoc; xmlSourceUrl = xmlUrl; JFrame frame = new JFrame (); buildMenus(); createLayout(); frame.getContentPane().add("Center", this); frame.setSize(1000, 600); frame.addWindowListener (new WindowAdapter () { public void windowClosing (WindowEvent e) { System.exit (0); }}); this.start(); frame.setVisible(true); editorList.addElement(this); } /** * Initializes the class **/ public void init () { if (xmlSourceUrl == null) { String xmlSource = getParameter("xmlsource"); try { xmlSourceUrl = new URL (getDocumentBase (), xmlSource); } catch (MalformedURLException ex) { ex.printStackTrace(); } String xslSource = getParameter ("xslsource"); try { xslSourceUrl = new URL (getDocumentBase (), xslSource); } catch (MalformedURLException ex) { ex.printStackTrace(); } String sklSource = getParameter ("sklsource"); if (sklSource != null) { try { sklSourceUrl = new URL (getDocumentBase (), sklSource); } catch (MalformedURLException ex) { ex.printStackTrace(); } } } xmlSource = xmlSourceUrl.toString(); xmlSourceDoc = readDocument(xmlSourceUrl); xslSourceDoc = readDocument(xslSourceUrl); if (sklSourceUrl != null) sklSourceDoc = readDocument(sklSourceUrl); initView(); buildMenus(); createLayout(); } /** * Builds the menus used in the interface **/ private void buildMenus() { JMenuBar menuBar; JMenu menu; JRadioButtonMenuItem rbMenuItem; //Create the menu bar. menuBar = new JMenuBar(); this.setJMenuBar(menuBar); //Build the first menu. menu = new JMenu("File"); menu.getAccessibleContext().setAccessibleDescription( "File menu"); menuBar.add(menu); loadXMLMenu = new JMenuItem("Load XML source document..."); loadXMLMenu.getAccessibleContext().setAccessibleDescription("Load a new XML document"); loadXMLMenu.addActionListener(this); menu.add(loadXMLMenu); loadXSLMenu = new JMenuItem("Load XSL transformation file..."); loadXSLMenu.getAccessibleContext().setAccessibleDescription("Load a new XSL document"); loadXSLMenu.addActionListener(this); menu.add(loadXSLMenu); saveXMLMenu = new JMenuItem("Save XML file"); saveXMLMenu.getAccessibleContext().setAccessibleDescription("Save the edited XML document"); saveXMLMenu.addActionListener(this); menu.add(saveXMLMenu); saveXMLAsMenu = new JMenuItem("Save XML file as..."); saveXMLAsMenu.getAccessibleContext().setAccessibleDescription("Save the edited XML document with a new name"); saveXMLAsMenu.addActionListener(this); menu.add(saveXMLAsMenu); quitAndSaveMenu = new JMenuItem("Quit and save"); quitAndSaveMenu.getAccessibleContext().setAccessibleDescription("Quit the editor and save changes"); quitAndSaveMenu.addActionListener(this); menu.add(quitAndSaveMenu); quitAndDiscardMenu = new JMenuItem("Quit and discard"); quitAndDiscardMenu.getAccessibleContext().setAccessibleDescription("Quit the editor and discard changes"); quitAndDiscardMenu.addActionListener(this); menu.add(quitAndDiscardMenu); //Build the second menu. menu = new JMenu("View"); menu.getAccessibleContext().setAccessibleDescription( "View menu"); menuBar.add(menu); // newViewMenu = new JMenuItem("New"); // newViewMenu.getAccessibleContext().setAccessibleDescription("Open a new view on the document"); // newViewMenu.addActionListener(this); // menu.add(newViewMenu); viewSourceMenu = new JCheckBoxMenuItem("Document Source"); viewSourceMenu.getAccessibleContext().setAccessibleDescription("View the source of the edited document"); viewSourceMenu.addItemListener(this); menu.add(viewSourceMenu); } /** * Creates an instance of XBMapper and process the document **/ private void createLayout() { try { xbm = new XBMapper(xmlSourceDoc, xslSourceDoc, sklSourceDoc); xbm.processBM(); } catch (Exception e) { e.printStackTrace(); } xbm.addXEditListener(this); updateView(); } /** * Updates the beans and request the redisplay of the view **/ private void updateLayout() { try { xbm.updateBeans(null); } catch (Exception e) { e.printStackTrace(); System.exit(1); } updateView(); } /** * Updates the view **/ public void updateView() { resultBeansView.setViewportView((Component)xbm.getRootBean()); if (sourceVisible) { sourceComp.setText(serialize(xbm.getXmlDocument())); sourceComp.select(0,0); } this.getContentPane().validate(); ((Component)xbm.getRootBean()).validate(); } /** * Parses the arguments of the command line *

* Two or three parameters can be specifed in the command line. * if there is two parameters presents, they represents * 1- the location of the source XML document * 2- the location of the XSLT document * * if there is three parameters presents, the third represents : * 3- the location of the skeleton document **/ private void parseArgs(String[] args) { // parse the arguments boolean error = false; if ((args.length < 2) || (args.length > 3)) error = true; else { String xmlSource = args[0]; try { xmlSourceUrl = new URL(xmlSource); } catch (MalformedURLException ex) { try { File f = new File(xmlSource); String addr="file:" + f.getAbsolutePath(); xmlSourceUrl = new URL(addr); } catch (MalformedURLException ex2) { ex2.printStackTrace(); } } String xslSource = args[1]; try { xslSourceUrl = new URL(xslSource); } catch (MalformedURLException ex) { try { File f = new File(xslSource); String addr="file:" + f.getAbsolutePath(); xslSourceUrl = new URL(addr); } catch (MalformedURLException ex2) { ex2.printStackTrace(); } } if (args.length == 3) { String sklSource = args[2]; try { sklSourceUrl = new URL(sklSource); } catch (MalformedURLException ex) { try { File f = new File(sklSource); String addr="file:" + f.getAbsolutePath(); sklSourceUrl = new URL(addr); } catch (MalformedURLException ex2) { ex2.printStackTrace(); } } } } if ( error) { System.err.println("BeansEdit: invalid parameters"); System.err.println("use: java bo.BeansEdit "); System.exit (1); } } /** * Reads the document at the location specified by sourceUrl **/ private Document readDocument(URL sourceUrl) { return readDocument(sourceUrl.toString()); } /** * Reads the document at the location specified by uri **/ private Document readDocument(String uri) { Document doc = null; try { // Using XERCES parser org.apache.xerces.parsers.DOMParser parser; parser = new org.apache.xerces.parsers.DOMParser(); // specifying validation boolean validate = false; parser.setFeature("http://xml.org/sax/features/validation", validate); // specifying nameSpace processing boolean nameSpaceProcessing = true; parser.setFeature("http://xml.org/sax/features/namespaces", nameSpaceProcessing); parser.parse(uri); // querying document after parse doc = parser.getDocument(); } catch (IOException e) { System.err.println("Error reading source document: "+uri); } catch (SAXException e) { System.err.println("Error reading source document: "+uri); } return doc; } /** * Serializes a DOM document **/ private String serialize(Document doc) { java.io.StringWriter sw = new java.io.StringWriter(); org.apache.xml.serialize.OutputFormat of = new org.apache.xml.serialize.OutputFormat(); of.setIndent(2); of.setIndenting(true); of.setLineWidth(40); org.apache.xml.serialize.XMLSerializer serializer = new org.apache.xml.serialize.XMLSerializer(sw, of); try { serializer.serialize(doc); } catch (Exception e) { e.printStackTrace(); } return sw.toString(); } /** * Handler for XEdit events. **/ public void xEditPerformed(XEditEvent xe) { if ((xe.getEventType() == XEditEvent.CHANGED) || (xe.getEventType() == XEditEvent.REMOVED) || (xe.getEventType() == XEditEvent.ADDED)) { this.updateLayout(); for (Enumeration e = editorList.elements() ; e.hasMoreElements() ;) { BeansEdit editor = (BeansEdit)e.nextElement(); if (editor == this) continue; editor.updateLayout(); } } } /** * Handler for action events. **/ public void actionPerformed(ActionEvent e) { if (e.getSource() == quitAndDiscardMenu) { System.exit(0); } else if (e.getSource() == quitAndSaveMenu) { StringWriter sw = new StringWriter(); OutputFormat of = new OutputFormat(); of.setIndent(2); of.setIndenting(true); XMLSerializer serializer = new XMLSerializer(sw, of); try { serializer.serialize(xbm.getXmlDocument()); } catch (Exception ex) { ex.printStackTrace(); } System.out.println(sw.toString()); System.exit(0); } else if (e.getSource() == loadXMLMenu) { final JFileChooser fc = new JFileChooser("."); int returnVal = fc.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); xmlSource = file.toString(); xmlSourceDoc = readDocument(file.toString()); createLayout(); } } else if (e.getSource() == loadXSLMenu) { final JFileChooser fc = new JFileChooser("."); int returnVal = fc.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); xslSourceDoc = readDocument(file.toString()); createLayout(); } } else if (e.getSource() == saveXMLMenu) { try { FileOutputStream os = new FileOutputStream(xmlSource); os.write(serialize(xmlSourceDoc).getBytes()); } catch (IOException ioe) { System.err.println("Error while saving XML document"); System.err.println(" operation aborted"); } } else if (e.getSource() == saveXMLAsMenu) { final JFileChooser fc = new JFileChooser("."); int returnVal = fc.showSaveDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); try { FileOutputStream os = new FileOutputStream(file); os.write(serialize(xmlSourceDoc).getBytes()); } catch (IOException ioe) { System.err.println("Error while saving XML document"); System.err.println(" operation aborted"); } xmlSource = file.toString(); } } else if (e.getSource() == newViewMenu) { BeansEdit b = new BeansEdit(xmlSourceDoc, xslSourceDoc, sklSourceDoc, xmlSourceUrl); // new Thread(b).start(); } } /** * Handler for item events. **/ public void itemStateChanged(ItemEvent e) { if (e.getSource() == viewSourceMenu) { if (e.getStateChange() == ItemEvent.SELECTED) { sourceVisible = true; } else { sourceVisible = false; dividerLocation = splitPane.getDividerLocation(); } initView(); updateView(); } } /** * Constructs the view which is displayed on the frame **/ private void initView() { this.getContentPane().removeAll(); resultBeansView = new JScrollPane(); if (!sourceVisible) { this.getContentPane().add(resultBeansView); } else { sourceComp = new JTextArea(); sourceComp.select(0,0); sourceComp.setEnabled(false); sourceView = new JScrollPane(sourceComp); splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sourceView, resultBeansView); splitPane.setDividerLocation(dividerLocation); this.getContentPane().add (splitPane); } } }