package org.nightlabs.jfire.trade.admin.ui.deliveryqueue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import javax.jdo.JDOHelper;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.nightlabs.base.ui.composite.XComposite;
import org.nightlabs.base.ui.job.Job;
import org.nightlabs.base.ui.notification.IDirtyStateManager;
import org.nightlabs.base.ui.util.RCPUtil;
import org.nightlabs.jfire.base.JFireEjb3Factory;
import org.nightlabs.jfire.base.login.ui.Login;
import org.nightlabs.jfire.security.GlobalSecurityReflector;
import org.nightlabs.jfire.store.StoreManagerRemote;
import org.nightlabs.jfire.store.deliver.DeliveryQueue;
import org.nightlabs.jfire.store.deliver.DeliveryQueueConfigModule;
import org.nightlabs.jfire.store.deliver.DeliveryQueueDAO;
import org.nightlabs.jfire.store.deliver.id.DeliveryQueueID;
import org.nightlabs.jfire.trade.admin.ui.resource.Messages;
import org.nightlabs.progress.NullProgressMonitor;
import org.nightlabs.progress.ProgressMonitor;
public class DeliveryQueueConfigurationComposite extends XComposite {
private DeliveryQueueTableComposite pqTableComposite;
private Button addQueueButton;
private Button editQueueButton;
private Button delQueueButton;
private Collection<DeliveryQueue> deliveryQueues;
private Collection<DeliveryQueue> changedDeliveryQueues = new LinkedList<DeliveryQueue>();
private IDirtyStateManager dirtyStateManager;
private DeliveryQueueConfigModule cfMod;
private boolean pqsLoaded = false;
public DeliveryQueueConfigurationComposite(Composite parent, IDirtyStateManager dirtyStateManager) {
super(parent, SWT.NONE, LayoutMode.TIGHT_WRAPPER, LayoutDataMode.GRID_DATA);
this.dirtyStateManager = dirtyStateManager;
XComposite wrapper = new XComposite(this, SWT.NONE, LayoutMode.ORDINARY_WRAPPER, LayoutDataMode.GRID_DATA, 2);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
new Label(wrapper, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(gd); // Spacer
XComposite spaceWrapper = new XComposite(wrapper, SWT.NONE, LayoutMode.ORDINARY_WRAPPER);
new Label(spaceWrapper, SWT.NONE).setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.visibleDeliveryQueuesLabel.text")); //$NON-NLS-1$
new Button(wrapper, SWT.NONE).setVisible(false);
pqTableComposite = new DeliveryQueueTableComposite(spaceWrapper);
pqTableComposite.addCheckStateChangedListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e) {
if (!pqsLoaded)
return;
if (! isReadOnly())
DeliveryQueueConfigurationComposite.this.dirtyStateManager.markDirty();
}
});
pqTableComposite.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
if (e1 instanceof DeliveryQueue && e2 instanceof DeliveryQueue) {
return ((DeliveryQueue) e1).getName().getText().compareTo(((DeliveryQueue) e2).getName().getText());
}
return 0;
}
});
spaceWrapper.getGridData().verticalSpan = 5;
XComposite.configureLayout(LayoutMode.ORDINARY_WRAPPER, pqTableComposite.getGridLayout());
Composite buttonComp = new XComposite(wrapper, SWT.NONE, LayoutMode.TIGHT_WRAPPER);
buttonComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
addQueueButton = new Button(buttonComp, SWT.NONE);
addQueueButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
addQueueButton.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.addQueueButton.text")); //$NON-NLS-1$
addQueueButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {}
public void widgetSelected(SelectionEvent e) {
addDeliveryQueue();
}
});
editQueueButton = new Button(buttonComp, SWT.NONE);
editQueueButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
editQueueButton.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.editQueueButton.text")); //$NON-NLS-1$
editQueueButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {}
public void widgetSelected(SelectionEvent e) {
editSelectedDeliveryQueue();
}
});
delQueueButton = new Button(buttonComp, SWT.NONE);
delQueueButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
delQueueButton.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.removeQueueButton.text")); //$NON-NLS-1$
delQueueButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {}
public void widgetSelected(SelectionEvent e) {
deleteSelectedDeliveryQueue();
}
});
populateDeliveryQueueList();
}
void populateDeliveryQueueList() {
String loadingMsg = Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.loadDeliveryQueuesJob.name"); //$NON-NLS-1$
pqTableComposite.setInput(new String[] { loadingMsg });
Job loadJob = new Job(loadingMsg) {
@Override
protected IStatus run(ProgressMonitor monitor) {
try {
StoreManagerRemote storeManager = getStoreManager();
Collection<DeliveryQueueID> deliveryQueueIds = storeManager.getAvailableDeliveryQueueIDs(false);
deliveryQueues = new ArrayList<DeliveryQueue>(
DeliveryQueueDAO.sharedInstance().getDeliveryQueues(deliveryQueueIds, new String[] {DeliveryQueue.FETCH_GROUP_NAME, DeliveryQueue.FETCH_GROUP_HAS_PENDING_DELIVERIES}, 2, new NullProgressMonitor()));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
Display.getDefault().asyncExec(new Runnable() {
public void run() {
pqTableComposite.setInput(deliveryQueues);
pqsLoaded = true;
if (cfMod != null) {
pqTableComposite.setCheckedElements(cfMod.getVisibleDeliveryQueues());
}
}
});
return Status.OK_STATUS;
}
};
loadJob.setPriority(Job.SHORT);
loadJob.schedule();
}
protected void updateGUI() {
pqTableComposite.refresh(true);
}
/**
* Flag whether the displayed delivery queues are read only or not.
*/
private boolean readOnly = false;
/**
* Sets whether the delivery queue configuration is read only or not.
* @param readOnly whether the delivery queue configuration is read only or not.
*/
public void setReadOnly(boolean readOnly)
{
if (this.readOnly == readOnly)
return;
this.readOnly = readOnly;
final boolean editable = ! readOnly;
addQueueButton.setEnabled(editable);
editQueueButton.setEnabled(editable);
delQueueButton.setEnabled(editable);
pqTableComposite.setEditable(editable);
}
/**
* Returns whether the delivery queue configuration is read only or not.
* @return whether the delivery queue configuration is read only or not.
*/
public boolean isReadOnly()
{
return readOnly;
}
private List<DeliveryQueue> checkedQueues;
private void storeCheckedDeliveryQueues() {
checkedQueues = pqTableComposite.getCheckedElements();
}
private void restoreCheckedDeliveryQueues() {
if (checkedQueues != null) {
pqTableComposite.setCheckedElements(checkedQueues);
checkedQueues = null;
}
}
void addDeliveryQueue() {
DeliveryQueue deliveryQueue = new DeliveryQueue(GlobalSecurityReflector.sharedInstance().getUserDescriptor().getOrganisationID());
Dialog dialog = new DeliveryQueueNameEditDialog(RCPUtil.getActiveShell(), deliveryQueue);
if (dialog.open() == Window.OK) {
deliveryQueues.add(deliveryQueue);
changedDeliveryQueues.add(deliveryQueue);
// TODO WORKAROUND to circumvent the JFace bug that checkbox states are not correctly updated
// when an element is deleted or removed from the model and the view is refreshed.
// We therefore remember the checked queues before updating the view and reset them thereafter.
storeCheckedDeliveryQueues();
updateGUI();
restoreCheckedDeliveryQueues();
dirtyStateManager.markDirty();
}
}
void editSelectedDeliveryQueue() {
DeliveryQueue deliveryQueue = pqTableComposite.getFirstSelectedElement();
if (deliveryQueue == null){
return;
}
Dialog dialog = new DeliveryQueueNameEditDialog(RCPUtil.getActiveShell(), deliveryQueue);
if (dialog.open() == Window.OK) {
// TODO WORKAROUND to circumvent the JFace bug that checkbox states are not correctly updated
// when an element is deleted or removed from the model and the view is refreshed.
// We therefore delete the element from the model and the view manually without refreshing the view.
changedDeliveryQueues.add(deliveryQueue);
// pqTableComposite.getTableViewer().add(deliveryQueue);
// END WORKAROUND
storeCheckedDeliveryQueues();
updateGUI();
restoreCheckedDeliveryQueues();
dirtyStateManager.markDirty();
}
}
void deleteSelectedDeliveryQueue() {
DeliveryQueue selectedQueue = pqTableComposite.getFirstSelectedElement();
if (selectedQueue != null
&& MessageDialog.openQuestion(RCPUtil.getActiveShell(), Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.deleteConfirmationDialog.title"), Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.deleteConfirmationDialog.message")) == true) { //$NON-NLS-1$ //$NON-NLS-2$
// Only delivery queues that have yet been persisted have to be marked as deleted.
// All others can simply be deleted
if (JDOHelper.isDetached(selectedQueue)) {
if (selectedQueue.hasPendingDeliveries()) {
String message = Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.DeliveryQueueDeletionImpossible.message"); //$NON-NLS-1$
MessageDialog.openError(RCPUtil.getActiveShell(), Messages.getString("org.nightlabs.jfire.trade.admin.ui.deliveryqueue.DeliveryQueueConfigurationComposite.DeliveryQueueDeletionImpossible.title"), message); //$NON-NLS-1$
return;
}
selectedQueue.markDefunct();
changedDeliveryQueues.add(selectedQueue);
}
deliveryQueues.remove(selectedQueue);
// TODO WORKAROUND to circumvent the JFace bug that checkbox states are not correctly updated
// when an element is deleted or removed from the model and the view is refreshed.
// We therefore delete the element from the model and the view manually without refreshing the view.
pqTableComposite.removeElement(selectedQueue);
// END WORKAROUND
updateGUI();
dirtyStateManager.markDirty();
}
}
void storeChanges(DeliveryQueueConfigModule configModule) {
try {
StoreManagerRemote storeManager = getStoreManager();
// cleanup the list of delivery queues that have to be persisted manually
List<DeliveryQueue> visibleDeliveryQueues = pqTableComposite.getCheckedElements();
for (DeliveryQueue pq : visibleDeliveryQueues) {
changedDeliveryQueues.remove(pq);
}
// end cleanup
storeManager.storeDeliveryQueues(changedDeliveryQueues, false, null, 1);
configModule.setVisibleDeliveryQueues(visibleDeliveryQueues);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private StoreManagerRemote storeManager;
private StoreManagerRemote getStoreManager() {
if (storeManager != null)
return storeManager;
try {
storeManager = JFireEjb3Factory.getRemoteBean(StoreManagerRemote.class, Login.getLogin().getInitialContextProperties());
return storeManager;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
void loadData(DeliveryQueueConfigModule configModule) {
this.cfMod = configModule;
if (cfMod != null) {
pqTableComposite.setCheckedElements(cfMod.getVisibleDeliveryQueues());
}
updateGUI();
}
}