/*
* eXist Open Source Native XML Database
*
* Copyright (C) 2001-06 Wolfgang M. Meier wolfgang@exist-db.org
*
* 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.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import javax.swing.Box;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.TitledBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.exist.collections.CollectionConfigurationManager;
import org.exist.storage.DBBroker;
import org.exist.xmldb.XmldbURI;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.XMLDBException;
/**
* Dialog for viewing and editing Triggers in the Admin Client
*
* @author Adam Retter <adam.retter@devon.gov.uk>
* @serial 2006-08-25
* @version 1.0
*/
class TriggersDialog extends JFrame {
private CollectionXConf cx = null;
private JComboBox cmbCollections;
private JTable tblTriggers;
private TriggersTableModel triggersModel;
private TableColumn colStoreDocument;
private TableColumn colUpdateDocument;
private TableColumn colRemoveDocument;
private TableColumn colCreateCollection;
private TableColumn colRenameCollection;
private TableColumn colDeleteCollection;
private InteractiveClient client;
public TriggersDialog(String title, InteractiveClient client)
{
super(title);
this.client = client;
//capture the frame's close event
WindowListener windowListener = new WindowAdapter()
{
public void windowClosing (WindowEvent e)
{
saveChanges();
TriggersDialog.this.setVisible(false);
TriggersDialog.this.dispose();
}
};
this.addWindowListener(windowListener);
//draw the GUI
setupComponents();
//Get the indexes for the root collection
actionGetTriggers(DBBroker.ROOT_COLLECTION);
}
private void setupComponents()
{
//Dialog Content Panel
GridBagLayout grid = new GridBagLayout();
getContentPane().setLayout(grid);
//Constraints for Layout
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(2, 2, 2, 2);
//collection label
JLabel label = new JLabel("Collection");
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
getContentPane().add(label);
//get the collections but not system collections
ArrayList alCollections = new ArrayList();
try
{
Collection root = client.getCollection(DBBroker.ROOT_COLLECTION);
ArrayList alAllCollections = getCollections(root, new ArrayList());
for(int i = 0; i < alAllCollections.size(); i++)
{
//TODO : use XmldbURIs !
if(alAllCollections.get(i).toString().indexOf(CollectionConfigurationManager.CONFIG_COLLECTION) == -1)
{
alCollections.add(alAllCollections.get(i));
}
}
}
catch (XMLDBException e)
{
//showErrorMessage(e.getMessage(), e);
return;
}
//Create a combobox listing the collections
cmbCollections = new JComboBox(alCollections.toArray());
cmbCollections.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
saveChanges();
JComboBox cb = (JComboBox)e.getSource();
actionGetTriggers(cb.getSelectedItem().toString());
}
});
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 1;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
grid.setConstraints(cmbCollections, c);
getContentPane().add(cmbCollections);
//Panel to hold controls relating to the Triggers Index
JPanel panelTriggers = new JPanel();
panelTriggers.setBorder(new TitledBorder("Triggers"));
GridBagLayout panelTriggersGrid = new GridBagLayout();
panelTriggers.setLayout(panelTriggersGrid);
//Table to hold the Triggers with Sroll bar
triggersModel = new TriggersTableModel();
tblTriggers = new JTable(triggersModel);
tblTriggers.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
tblTriggers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
colStoreDocument = tblTriggers.getColumnModel().getColumn(1);
colStoreDocument.setCellEditor(new CheckBoxCellEditor());
colStoreDocument.setCellRenderer(new CheckBoxCellRenderer());
colUpdateDocument = tblTriggers.getColumnModel().getColumn(2);
colUpdateDocument.setCellEditor(new CheckBoxCellEditor());
colUpdateDocument.setCellRenderer(new CheckBoxCellRenderer());
colRemoveDocument = tblTriggers.getColumnModel().getColumn(3);
colRemoveDocument.setCellEditor(new CheckBoxCellEditor());
colRemoveDocument.setCellRenderer(new CheckBoxCellRenderer());
colCreateCollection = tblTriggers.getColumnModel().getColumn(4);
colCreateCollection.setCellEditor(new CheckBoxCellEditor());
colCreateCollection.setCellRenderer(new CheckBoxCellRenderer());
colRenameCollection = tblTriggers.getColumnModel().getColumn(5);
colRenameCollection.setCellEditor(new CheckBoxCellEditor());
colRenameCollection.setCellRenderer(new CheckBoxCellRenderer());
colDeleteCollection = tblTriggers.getColumnModel().getColumn(6);
colDeleteCollection.setCellEditor(new CheckBoxCellEditor());
colDeleteCollection.setCellRenderer(new CheckBoxCellRenderer());
JScrollPane scrollFullTextIndexes = new JScrollPane(tblTriggers);
scrollFullTextIndexes.setPreferredSize(new Dimension(250, 150));
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
panelTriggersGrid.setConstraints(scrollFullTextIndexes, c);
panelTriggers.add(scrollFullTextIndexes);
//Toolbar with add/delete buttons for Triggers
Box triggersToolbarBox = Box.createHorizontalBox();
//add button
JButton btnAddTrigger = new JButton("Add");
btnAddTrigger.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
actionAddTrigger();
}
});
triggersToolbarBox.add(btnAddTrigger);
//delete button
JButton btnDeleteTrigger = new JButton("Delete");
btnDeleteTrigger.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
actionDeleteTrigger();
}
});
triggersToolbarBox.add(btnDeleteTrigger);
c.gridx = 0;
c.gridy = 4;
c.gridwidth = 2;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.BOTH;
c.weightx = 0;
c.weighty = 0;
panelTriggersGrid.setConstraints(triggersToolbarBox, c);
panelTriggers.add(triggersToolbarBox);
//add triggers panel to content frame
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
grid.setConstraints(panelTriggers, c);
getContentPane().add(panelTriggers);
pack();
}
//if changes have been made, allows the user to save them
private void saveChanges()
{
//the collection has been changed
if(cx.hasChanged())
{
//ask the user if they would like to save the changes
int result = JOptionPane.showConfirmDialog(getContentPane(), "The configuration for the collection has changed, would you like to save the changes?", "Save Changes", JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.YES_OPTION)
{
//save the collection.xconf changes
if(cx.Save())
{
//save ok
JOptionPane.showMessageDialog(getContentPane(), "Your changes have been saved.");
}
else
{
//save failed
JOptionPane.showMessageDialog(getContentPane(), "Unable to save changes!");
}
}
}
}
//THIS IS A COPY FROM ClientFrame
//TODO: share this code between the two classes
private ArrayList getCollections(Collection root, ArrayList collectionsList) throws XMLDBException
{
collectionsList.add(new PrettyXmldbURI(XmldbURI.create(root.getName())));
String[] childCollections= root.listChildCollections();
Collection child;
for(int i = 0; i < childCollections.length; i++)
{
child = root.getChildCollection(childCollections[i]);
getCollections(child, collectionsList);
}
return collectionsList;
}
private void actionAddTrigger()
{
triggersModel.addRow();
}
private void actionDeleteTrigger()
{
int iSelectedRow = tblTriggers.getSelectedRow();
if(iSelectedRow > -1 )
{
triggersModel.removeRow(iSelectedRow);
}
}
//Displays the indexes when a collection is selection
private void actionGetTriggers(String collectionName)
{
try
{
cx = new CollectionXConf(collectionName, client);
triggersModel.fireTableDataChanged();
}
catch(XMLDBException xe)
{
//TODO: CONSIDER whether CollectionXConf Should throw xmldb exception at all?
}
}
public class CheckBoxCellRenderer extends JCheckBox implements TableCellRenderer
{
public CheckBoxCellRenderer()
{
setHorizontalAlignment(JLabel.CENTER);
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if(isSelected)
{
setForeground(table.getSelectionForeground());
//super.setBackground(table.getSelectionBackground());
setBackground(table.getSelectionBackground());
}
else
{
setForeground(table.getForeground());
setBackground(table.getBackground());
}
// Set the state
setSelected((value != null && ((Boolean) value).booleanValue()));
return this;
}
}
public class CheckBoxCellEditor extends DefaultCellEditor
{
public CheckBoxCellEditor()
{
super(new JCheckBox());
}
}
class TriggersTableModel extends AbstractTableModel
{
private final String[] columnNames = new String[] { "class", "Store Document", "Update Document", "Remove Document", "Create Collection", "Rename Collection", "Delete Collection" };
public TriggersTableModel()
{
super();
fireTableDataChanged();
}
/* (non-Javadoc)
* @see javax.swing.table.TableModel#isCellEditable()
*/
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
{
String triggerClass = null;
boolean STORE_DOCUMENT_EVENT = ((Boolean)colStoreDocument.getCellEditor().getCellEditorValue()).booleanValue();
boolean UPDATE_DOCUMENT_EVENT = ((Boolean)colUpdateDocument.getCellEditor().getCellEditorValue()).booleanValue();
boolean REMOVE_DOCUMENT_EVENT = ((Boolean)colRemoveDocument.getCellEditor().getCellEditorValue()).booleanValue();
boolean CREATE_COLLECTION_EVENT = ((Boolean)colCreateCollection.getCellEditor().getCellEditorValue()).booleanValue();
boolean RENAME_COLLECTION_EVENT = ((Boolean)colRenameCollection.getCellEditor().getCellEditorValue()).booleanValue();
boolean DELETE_COLLECTION_EVENT = ((Boolean)colDeleteCollection.getCellEditor().getCellEditorValue()).booleanValue();
if(columnIndex == 0)
{
//trigger class name has been updated
triggerClass = (String)aValue;
}
cx.updateTrigger(rowIndex, triggerClass, STORE_DOCUMENT_EVENT, UPDATE_DOCUMENT_EVENT, REMOVE_DOCUMENT_EVENT, CREATE_COLLECTION_EVENT, RENAME_COLLECTION_EVENT, DELETE_COLLECTION_EVENT, null);
fireTableCellUpdated(rowIndex, columnIndex);
}
public void removeRow(int rowIndex)
{
cx.deleteTrigger(rowIndex);
fireTableRowsDeleted(rowIndex, rowIndex);
}
public void addRow()
{
cx.addTrigger("", false, false, false, false, false, false, null);
fireTableRowsInserted(getRowCount(), getRowCount() + 1);
}
/* (non-Javadoc)
* @see javax.swing.table.TableModel#isCellEditable()
*/
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return true;
}
/* (non-Javadoc)
* @see javax.swing.table.TableModel#getColumnCount()
*/
public int getColumnCount()
{
return columnNames.length;
}
/* (non-Javadoc)
* @see javax.swing.table.TableModel#getColumnName(int)
*/
public String getColumnName(int column)
{
return columnNames[column];
}
/* (non-Javadoc)
* @see javax.swing.table.TableModel#getRowCount()
*/
public int getRowCount()
{
return cx != null ? cx.getTriggerCount() : 0;
}
/* (non-Javadoc)
* @see javax.swing.table.TableModel#getValueAt(int, int)
*/
public Object getValueAt(int rowIndex, int columnIndex)
{
switch (columnIndex)
{
/* class */
case 0:
return cx.getTrigger(rowIndex).getTriggerClass();
/* events */
case 1 : //store document
return new Boolean(cx.getTrigger(rowIndex).getStoreDocumentEvent());
case 2 : //update document
return new Boolean(cx.getTrigger(rowIndex).getUpdateDocumentEvent());
case 3 : //remove document
return new Boolean(cx.getTrigger(rowIndex).getRemoveDocumentEvent());
case 4 : //create collection
return new Boolean(cx.getTrigger(rowIndex).getCreateCollectionEvent());
case 5 : //rename collection
return new Boolean(cx.getTrigger(rowIndex).getRenameCollectionEvent());
case 6 : //delete collection
return new Boolean(cx.getTrigger(rowIndex).getDeleteCollectionEvent());
default :
return null;
}
}
}
}