/* * eXist Open Source Native XML Database Copyright (C) 2001-06 Wolfgang M. * Meier wolfgang@exist-db.org http://exist.sourceforge.net * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ package org.exist.client; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.util.Observable; import java.util.Observer; import java.util.Properties; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JToolBar; import javax.swing.KeyStroke; import javax.swing.border.BevelBorder; import javax.xml.transform.OutputKeys; import org.exist.security.User; import org.exist.storage.ElementIndex; import org.exist.storage.TextSearchEngine; import org.exist.util.ProgressIndicator; import org.exist.xmldb.UserManagementService; import org.exist.xmldb.XmldbURI; import org.exist.xquery.util.URIUtils; import org.xmldb.api.base.Collection; import org.xmldb.api.base.Resource; import org.xmldb.api.base.XMLDBException; import org.xmldb.api.modules.XMLResource; class DocumentView extends JFrame { protected InteractiveClient client; private XmldbURI resourceName; protected Resource resource; protected Collection collection; protected boolean readOnly = false; protected ClientTextArea text; protected JButton saveButton; protected JButton saveAsButton; protected JTextField statusMessage; protected JTextField positionDisplay; protected JProgressBar progress; protected JPopupMenu popup; protected Properties properties; public DocumentView(InteractiveClient client, XmldbURI resourceName, Properties properties) throws XMLDBException { super( URIUtils.urlDecodeUtf8(resourceName.lastSegment()) ); this.resourceName = resourceName; this.resource = client.retrieve(resourceName, properties.getProperty(OutputKeys.INDENT, "yes")); //$NON-NLS-1$ this.client = client; this.collection = client.getCollection(); this.properties = properties; getContentPane().setLayout(new BorderLayout()); setupComponents(); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent ev) { close(); } }); pack(); } public void viewDocument() { try{ if (resource.getResourceType().equals("XMLResource")) //$NON-NLS-1$ setText((String) resource.getContent()); else setText(new String((byte[]) resource.getContent())); // lock the resource for editing UserManagementService service = (UserManagementService) client.current.getService("UserManagementService", "1.0"); //$NON-NLS-1$ //$NON-NLS-2$ User user = service.getUser(properties.getProperty("user")); //$NON-NLS-1$ String lockOwner = service.hasUserLock(resource); if(lockOwner != null) { if(JOptionPane.showConfirmDialog(this, Messages.getString("DocumentView.6") + lockOwner + //$NON-NLS-1$ Messages.getString("DocumentView.7"), //$NON-NLS-1$ Messages.getString("DocumentView.8"), //$NON-NLS-1$ JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { dispose(); this.setCursor(Cursor.getDefaultCursor()); return; } } try { service.lockResource(resource, user); } catch(XMLDBException ex) { System.out.println(ex.getMessage()); JOptionPane.showMessageDialog(this, Messages.getString("DocumentView.9")); //$NON-NLS-1$ setReadOnly(); } setVisible(true); } catch (XMLDBException ex) { showErrorMessage(Messages.getString("DocumentView.10") + ex.getMessage(), ex); //$NON-NLS-1$ } } private static void showErrorMessage(String message, Throwable t) { JScrollPane scroll = null; JTextArea msgArea = new JTextArea(message); msgArea.setBorder(BorderFactory.createTitledBorder("Message:")); //$NON-NLS-1$ msgArea.setEditable(false); msgArea.setBackground(null); if (t != null) { StringWriter out = new StringWriter(); PrintWriter writer = new PrintWriter(out); t.printStackTrace(writer); JTextArea stacktrace = new JTextArea(out.toString(), 20, 50); stacktrace.setBackground(null); stacktrace.setEditable(false); scroll = new JScrollPane(stacktrace); scroll.setPreferredSize(new Dimension(250, 300)); scroll.setBorder(BorderFactory .createTitledBorder("Exception Stacktrace:")); //$NON-NLS-1$ } JOptionPane optionPane = new JOptionPane(); optionPane.setMessage(new Object[]{msgArea, scroll}); optionPane.setMessageType(JOptionPane.ERROR_MESSAGE); JDialog dialog = optionPane.createDialog(null, Messages.getString("DocumentView.13")); //$NON-NLS-1$ dialog.setResizable(true); dialog.pack(); dialog.setVisible(true); return; } public void setReadOnly() { text.setEditable(false); saveButton.setEnabled(false); readOnly = true; } private void close() { unlockView(); } private void unlockView() { if (readOnly) return; try { UserManagementService service = (UserManagementService) collection .getService("UserManagementService", "1.0"); //$NON-NLS-1$ //$NON-NLS-2$ service.unlockResource(resource); } catch (XMLDBException e) { e.printStackTrace(); } } private void setupComponents() throws XMLDBException { /* start of menubar */ JMenuBar menubar = new JMenuBar(); JMenu fileMenu = new JMenu(Messages.getString("DocumentView.16")); //$NON-NLS-1$ fileMenu.setMnemonic(KeyEvent.VK_F); menubar.add(fileMenu); JMenuItem item; // Save to database item = new JMenuItem(Messages.getString("DocumentView.17"), KeyEvent.VK_S); //$NON-NLS-1$ item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("SAVE"); save(); } }); fileMenu.add(item); /* // Refresh item = new JMenuItem("Refresh", KeyEvent.VK_R); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { refresh() ; } catch (XMLDBException u) { u.printStackTrace(); } } }); fileMenu.add(item); */ setJMenuBar(menubar); /* end of menubar */ /* The icon toolbar */ JToolBar toolbar = new JToolBar(); //Save button URL url = getClass().getResource("icons/Save24.gif"); //$NON-NLS-1$ saveButton = new JButton(new ImageIcon(url)); saveButton .setToolTipText(Messages.getString("DocumentView.20")); //$NON-NLS-1$ saveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { save(); } }); toolbar.add(saveButton); //Save As button url = getClass().getResource("icons/SaveAs24.gif"); //$NON-NLS-1$ saveAsButton = new JButton(new ImageIcon(url)); saveAsButton .setToolTipText(Messages.getString("DocumentView.22")); //$NON-NLS-1$ saveAsButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { saveAs(); } }); toolbar.add(saveAsButton); //Export button url = getClass().getResource("icons/Export24.gif"); //$NON-NLS-1$ JButton button = new JButton(new ImageIcon(url)); button.setToolTipText(Messages.getString("DocumentView.24")); //$NON-NLS-1$ button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { export() ; } catch (XMLDBException u) { u.printStackTrace(); } } }); toolbar.add(button); toolbar.addSeparator(); //Copy button url = getClass().getResource("icons/Copy24.gif"); //$NON-NLS-1$ button = new JButton(new ImageIcon(url)); button.setToolTipText(Messages.getString("DocumentView.26")); //$NON-NLS-1$ button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { text.copy(); } }); toolbar.add(button); //Cut button url = getClass().getResource("icons/Cut24.gif"); //$NON-NLS-1$ button = new JButton(new ImageIcon(url)); button.setToolTipText(Messages.getString("DocumentView.28")); //$NON-NLS-1$ button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { text.cut(); } }); toolbar.add(button); //Paste button url = getClass().getResource("icons/Paste24.gif"); //$NON-NLS-1$ button = new JButton(new ImageIcon(url)); button.setToolTipText(Messages.getString("DocumentView.30")); //$NON-NLS-1$ button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { text.paste(); } }); toolbar.add(button); toolbar.addSeparator(); //Refresh button url = getClass().getResource("icons/Refresh24.gif"); //$NON-NLS-1$ button = new JButton(new ImageIcon(url)); button.setToolTipText(Messages.getString("DocumentView.32")); //$NON-NLS-1$ button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { refresh() ; } catch (XMLDBException u) { u.printStackTrace(); } } }); toolbar.add(button); getContentPane().add(toolbar, BorderLayout.NORTH); text = new ClientTextArea(true, Messages.getString("DocumentView.33")); //$NON-NLS-1$ getContentPane().add(text, BorderLayout.CENTER); Box statusbar = Box.createHorizontalBox(); statusbar.setBorder(BorderFactory .createBevelBorder(BevelBorder.LOWERED)); statusMessage = new JTextField(20); statusMessage.setEditable(false); statusMessage.setFocusable(false); statusMessage.setText(Messages.getString("DocumentView.34") + URIUtils.urlDecodeUtf8(resource.getId()) + Messages.getString("DocumentView.35")); //$NON-NLS-1$ //$NON-NLS-2$ statusbar.add(statusMessage); progress = new JProgressBar(); progress.setPreferredSize(new Dimension(200, 30)); progress.setVisible(false); statusbar.add(progress); positionDisplay = new JTextField(5); positionDisplay.setEditable(false); positionDisplay.setFocusable(true); statusbar.add(positionDisplay); text.setPositionOutputTextArea(positionDisplay); getContentPane().add(statusbar, BorderLayout.SOUTH); } private void save() { new Thread() { public void run() { try { statusMessage.setText(Messages.getString("DocumentView.36") + URIUtils.urlDecodeUtf8(resource.getId())); //$NON-NLS-1$ if (collection instanceof Observable) ((Observable) collection) .addObserver(new ProgressObserver()); progress.setIndeterminate(true); progress.setVisible(true); resource.setContent(text.getText()); collection.storeResource(resource); if (collection instanceof Observable) ((Observable) collection).deleteObservers(); } catch (XMLDBException e) { ClientFrame.showErrorMessage(Messages.getString("DocumentView.37") //$NON-NLS-1$ + e.getMessage(), e); } finally { progress.setVisible(false); } } }.start(); } private void saveAs() { new Thread() { public void run() { //Get the name to save the resource as String nameres = JOptionPane.showInputDialog(null, Messages.getString("DocumentView.38")); //$NON-NLS-1$ if (nameres != null) { try { //Change status message and display a progress dialog statusMessage.setText(Messages.getString("DocumentView.39") + nameres); //$NON-NLS-1$ if (collection instanceof Observable) ((Observable) collection).addObserver(new ProgressObserver()); progress.setIndeterminate(true); progress.setVisible(true); //Create a new resource as named, set the content, store the resource XMLResource result = null; result = (XMLResource) collection.createResource(URIUtils.encodeXmldbUriFor(nameres).toString(), XMLResource.RESOURCE_TYPE); result.setContent(text.getText()); collection.storeResource(result); client.reloadCollection(); //reload the client collection if (collection instanceof Observable) ((Observable) collection).deleteObservers(); } catch (XMLDBException e) { ClientFrame.showErrorMessage(Messages.getString("DocumentView.40") + e.getMessage(), e); //$NON-NLS-1$ } catch (URISyntaxException e) { ClientFrame.showErrorMessage(Messages.getString("DocumentView.41") + e.getMessage(), e); //$NON-NLS-1$ } finally { //hide the progress dialog progress.setVisible(false); } } } }.start(); } private void export() throws XMLDBException { String workDir = properties.getProperty("working-dir", System //$NON-NLS-1$ .getProperty("user.dir")); //$NON-NLS-1$ JFileChooser chooser = new JFileChooser(workDir); chooser.setMultiSelectionEnabled(false); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setSelectedFile(new File(resource.getId())); if (chooser.showDialog(this, Messages.getString("DocumentView.44")) == JFileChooser.APPROVE_OPTION) { //$NON-NLS-1$ File file = chooser.getSelectedFile(); if (file.exists() && JOptionPane.showConfirmDialog(this, Messages.getString("DocumentView.45"), Messages.getString("DocumentView.46"), //$NON-NLS-1$ //$NON-NLS-2$ JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) return; try { OutputStreamWriter writer = new OutputStreamWriter( new FileOutputStream(file), Charset.forName(properties .getProperty("encoding"))); //$NON-NLS-1$ writer.write(text.getText()); writer.close(); } catch (IOException e) { ClientFrame.showErrorMessage(Messages.getString("DocumentView.48") //$NON-NLS-1$ + e.getMessage(), e); } File selectedDir = chooser.getCurrentDirectory(); properties .setProperty("working-dir", selectedDir.getAbsolutePath()); //$NON-NLS-1$ } } private void refresh() throws XMLDBException { //First unlock the resource unlockView(); //Reload the resource this.resource = client.retrieve(resourceName, properties.getProperty(OutputKeys.INDENT, "yes")); //$NON-NLS-1$ //View and lock the resource viewDocument(); } public void setText(String content) throws XMLDBException { text.setText(""); //$NON-NLS-1$ text.setText(content); text.setCaretPosition(0); text.scrollToCaret(); statusMessage.setText(Messages.getString("DocumentView.52") + XmldbURI.create(client.getCollection().getName()).append(resourceName) +Messages.getString("DocumentView.53")+properties.getProperty("uri")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } class ProgressObserver implements Observer { int mode = 0; public void update(Observable o, Object arg) { progress.setIndeterminate(false); ProgressIndicator ind = (ProgressIndicator) arg; progress.setValue(ind.getPercentage()); if (o instanceof TextSearchEngine) progress.setString("Storing words"); //$NON-NLS-1$ else if (o instanceof ElementIndex) progress.setString("Storing elements"); //$NON-NLS-1$ } } }