blob: f534294c92b28701c36e268169cef2851694d9bc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.jpa.eclipselink.ui.internal.details;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.util.List;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jpt.common.ui.WidgetFactory;
import org.eclipse.jpt.common.ui.internal.util.ControlSwitcher;
import org.eclipse.jpt.common.ui.internal.util.PaneEnabler;
import org.eclipse.jpt.common.ui.internal.widgets.AddRemoveListPane;
import org.eclipse.jpt.common.ui.internal.widgets.AddRemovePane.AbstractAdapter;
import org.eclipse.jpt.common.ui.internal.widgets.AddRemovePane.Adapter;
import org.eclipse.jpt.common.ui.internal.widgets.Pane;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.model.ChangeSupport;
import org.eclipse.jpt.common.utility.internal.model.SingleAspectChangeSupport;
import org.eclipse.jpt.common.utility.internal.model.value.CompositeListValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.ItemPropertyListValueModelAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.ListAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.swing.ObjectListSelectionModel;
import org.eclipse.jpt.common.utility.model.Model;
import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent;
import org.eclipse.jpt.common.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.common.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel;
import org.eclipse.jpt.jpa.core.JpaNode;
import org.eclipse.jpt.jpa.core.context.ReadOnlyNamedColumn;
import org.eclipse.jpt.jpa.eclipselink.core.context.ReadOnlyTenantDiscriminatorColumn2_3;
import org.eclipse.jpt.jpa.eclipselink.ui.internal.EclipseLinkHelpContextIds;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.PageBook;
/**
* Here is the layout of this pane:
* <pre>
* -----------------------------------------------------------------------------
* | ------------------------------------------------------------------------- |
* | | | |
* | | AddRemoveListPane | |
* | | | |
* | ------------------------------------------------------------------------- |
* -----------------------------------------------------------------------------</pre>
*
* @version 3.1
* @since 3.1
*/
public class TenantDiscriminatorColumnsComposite<T extends JpaNode> extends Pane<T>
{
/**
* The editor used to perform the common behaviors defined in the list pane.
*/
TenantDiscriminatorColumnsEditor<T> tenantDiscriminatorColumnsEditor;
private AddRemoveListPane<T> listPane;
private Pane<ReadOnlyTenantDiscriminatorColumn2_3> tenantDiscriminatorColumnPane;
private WritablePropertyValueModel<ReadOnlyTenantDiscriminatorColumn2_3> tenantDiscriminatorColumnHolder;
public TenantDiscriminatorColumnsComposite(Pane<? extends T> parentPane,
Composite parent,
TenantDiscriminatorColumnsEditor<T> tenantDiscriminatorColumnsEditor) {
super(parentPane, parent);
this.tenantDiscriminatorColumnsEditor = tenantDiscriminatorColumnsEditor;
initializeLayout2();
}
public TenantDiscriminatorColumnsComposite(Pane<?> parentPane,
PropertyValueModel<? extends T> subjectHolder,
Composite parent,
TenantDiscriminatorColumnsEditor<T> tenantDiscriminatorColumnsEditor,
boolean automaticallyAlignWidgets) {
super(parentPane, subjectHolder, parent, automaticallyAlignWidgets);
this.tenantDiscriminatorColumnsEditor = tenantDiscriminatorColumnsEditor;
initializeLayout2();
}
public TenantDiscriminatorColumnsComposite(PropertyValueModel<? extends T> subjectHolder,
Composite parent,
WidgetFactory widgetFactory,
TenantDiscriminatorColumnsEditor<T> tenantDiscriminatorColumnsEditor) {
super(subjectHolder, parent, widgetFactory);
this.tenantDiscriminatorColumnsEditor = tenantDiscriminatorColumnsEditor;
initializeLayout2();
}
@Override
protected void initialize() {
super.initialize();
this.tenantDiscriminatorColumnHolder = buildTenantDiscriminatorColumnHolder();
}
private WritablePropertyValueModel<ReadOnlyTenantDiscriminatorColumn2_3> buildTenantDiscriminatorColumnHolder() {
return new SimplePropertyValueModel<ReadOnlyTenantDiscriminatorColumn2_3>();
}
@Override
protected void initializeLayout(Composite container) {
//see intiailizeLayout2()
}
private void initializeLayout2() {
this.listPane = new AddRemoveListPane<T>(
this,
getControl(),
buildTenantDiscriminatorColumnsAdapter(),
buildTenantDiscriminatorColumnsListModel(),
this.tenantDiscriminatorColumnHolder,
buildTenantDiscriminatorColumnsListLabelProvider(),
EclipseLinkHelpContextIds.MULTITENANCY_TENANT_DISCRIMINATOR_COLUMNS,
false
);
// Property pane
PageBook pageBook = new PageBook(getControl(), SWT.NULL);
pageBook.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
//Tenant Discriminator Column property pane
this.tenantDiscriminatorColumnPane = this.buildTenantDiscriminatorColumnComposite(pageBook);
installPaneSwitcher(pageBook);
}
protected Pane<ReadOnlyTenantDiscriminatorColumn2_3> buildTenantDiscriminatorColumnComposite(PageBook pageBook) {
return new TenantDiscriminatorColumnComposite(
this,
this.tenantDiscriminatorColumnHolder,
pageBook
);
}
private void installPaneSwitcher(PageBook pageBook) {
new ControlSwitcher(this.tenantDiscriminatorColumnHolder, this.tenantDiscriminatorColumnPane.getControl(), pageBook);
}
String buildTenantDiscriminatorColumnLabel(ReadOnlyTenantDiscriminatorColumn2_3 tenantDiscriminatorColumn) {
if (tenantDiscriminatorColumn.isVirtual() || tenantDiscriminatorColumn.getSpecifiedName() == null) {
return NLS.bind(
EclipseLinkUiDetailsMessages.TenantDiscriminatorColumnComposite_defaultTenantDiscriminatorColumnNameLabel,
tenantDiscriminatorColumn.getName()
);
}
return tenantDiscriminatorColumn.getName();
}
private Adapter buildTenantDiscriminatorColumnsAdapter() {
return new AbstractAdapter() {
public void addNewItem(ObjectListSelectionModel listSelectionModel) {
TenantDiscriminatorColumnsComposite.this.tenantDiscriminatorColumnsEditor.addTenantDiscriminatorColumn(getSubject());
}
@Override
public boolean hasOptionalButton() {
return false;
}
public void removeSelectedItems(ObjectListSelectionModel listSelectionModel) {
TenantDiscriminatorColumnsComposite.this.tenantDiscriminatorColumnsEditor.removeTenantDiscriminatorColumns(getSubject(), listSelectionModel.selectedIndices());
}
};
}
private ListValueModel<ReadOnlyTenantDiscriminatorColumn2_3> buildTenantDiscriminatorColumnsListModel() {
return new LocalItemPropertyListValueModelAdapter<ReadOnlyTenantDiscriminatorColumn2_3>(buildTenantDiscriminatorColumnsListHolder(),
ReadOnlyNamedColumn.SPECIFIED_NAME_PROPERTY,
ReadOnlyNamedColumn.DEFAULT_NAME_PROPERTY);
}
private ListValueModel<ReadOnlyTenantDiscriminatorColumn2_3> buildTenantDiscriminatorColumnsListHolder() {
List<ListValueModel<ReadOnlyTenantDiscriminatorColumn2_3>> list = new ArrayList<ListValueModel<ReadOnlyTenantDiscriminatorColumn2_3>>();
list.add(buildDefaultTenantDiscriminatorColumnListHolder());
list.add(buildSpecifiedTenantDiscriminatorColumnsListHolder());
return new CompositeListValueModel<ListValueModel<ReadOnlyTenantDiscriminatorColumn2_3>, ReadOnlyTenantDiscriminatorColumn2_3>(list);
}
private ListValueModel<ReadOnlyTenantDiscriminatorColumn2_3> buildSpecifiedTenantDiscriminatorColumnsListHolder() {
return new ListAspectAdapter<T, ReadOnlyTenantDiscriminatorColumn2_3>(getSubjectHolder(), this.tenantDiscriminatorColumnsEditor.getSpecifiedTenantDiscriminatorsListPropertyName()) {
@Override
protected ListIterable<ReadOnlyTenantDiscriminatorColumn2_3> getListIterable() {
return TenantDiscriminatorColumnsComposite.this.tenantDiscriminatorColumnsEditor.getSpecifiedTenantDiscriminatorColumns(this.subject);
}
@Override
protected int size_() {
return TenantDiscriminatorColumnsComposite.this.tenantDiscriminatorColumnsEditor.getSpecifiedTenantDiscriminatorColumnsSize(this.subject);
}
};
}
private ListValueModel<ReadOnlyTenantDiscriminatorColumn2_3> buildDefaultTenantDiscriminatorColumnListHolder() {
return new ListAspectAdapter<T, ReadOnlyTenantDiscriminatorColumn2_3>(getSubjectHolder(), this.tenantDiscriminatorColumnsEditor.getDefaultTenantDiscriminatorsListPropertyName()) {
@Override
protected ListIterable<ReadOnlyTenantDiscriminatorColumn2_3> getListIterable() {
return TenantDiscriminatorColumnsComposite.this.tenantDiscriminatorColumnsEditor.getDefaultTenantDiscriminatorColumns(this.subject);
}
@Override
protected int size_() {
return TenantDiscriminatorColumnsComposite.this.tenantDiscriminatorColumnsEditor.getDefaultTenantDiscriminatorColumnsSize(this.subject);
}
};
}
private ILabelProvider buildTenantDiscriminatorColumnsListLabelProvider() {
return new LabelProvider() {
@Override
public String getText(Object element) {
return buildTenantDiscriminatorColumnLabel((ReadOnlyTenantDiscriminatorColumn2_3) element);
}
};
}
public void installListPaneEnabler(PropertyValueModel<Boolean> paneEnablerHolder) {
new PaneEnabler(paneEnablerHolder, this.listPane);
}
@Override
public void enableWidgets(boolean enabled) {
super.enableWidgets(enabled);
this.listPane.enableWidgets(enabled);
}
public void setSelectedTenantDiscriminatorColumn(ReadOnlyTenantDiscriminatorColumn2_3 tenantDiscriminatorColumn) {
this.listPane.setSelectedItem(tenantDiscriminatorColumn);
}
/**
* The editor is used to complete the behavior of this pane.
*/
public static interface TenantDiscriminatorColumnsEditor<T> {
/**
* Add a tenant discriminator column to the given subject
*/
void addTenantDiscriminatorColumn(T subject);
/**
* Return whether the subject has specified tenant discriminator columns
*/
boolean hasSpecifiedTenantDiscriminatorColumns(T subject);
/**
* Return the specified tenant discriminator from the given subject
*/
ListIterable<ReadOnlyTenantDiscriminatorColumn2_3> getSpecifiedTenantDiscriminatorColumns(T subject);
/**
* Return the number of specified join columns on the given subject
*/
int getSpecifiedTenantDiscriminatorColumnsSize(T subject);
/**
* Return the default tenant discriminator columns from the given subject or null.
*/
ListIterable<ReadOnlyTenantDiscriminatorColumn2_3> getDefaultTenantDiscriminatorColumns(T subject);
/**
* Return the number of default tenant discriminator on the given subject
*/
int getDefaultTenantDiscriminatorColumnsSize(T subject);
/**
* Return the property name of the specified tenant discriminator columns list
*/
String getSpecifiedTenantDiscriminatorsListPropertyName();
/**
* Return the property name of the default tenant discriminator columns list
*/
String getDefaultTenantDiscriminatorsListPropertyName();
/**
* Remove the tenant discriminator columns at the specified indices from the subject
*/
void removeTenantDiscriminatorColumns(T subject, int[] selectedIndices);
}
private class LocalItemPropertyListValueModelAdapter<E> extends ItemPropertyListValueModelAdapter<E> {
public LocalItemPropertyListValueModelAdapter(ListValueModel<E> listHolder, String... propertyNames) {
super(listHolder, propertyNames);
}
public LocalItemPropertyListValueModelAdapter(CollectionValueModel<E> collectionHolder, String[] propertyNames) {
super(collectionHolder, propertyNames);
}
/**
* bug 310720
* Override to just fire an itemReplaced event instead of a listChanged event.
* An aspect of the item as changed, so no reason to say that the entire list has changed.
* Added a LocalChangeSupport so that I can fire a ListReplacedEvent for an old list
* and new list containing the same item.
*/
@Override
protected void itemAspectChanged(EventObject event) {
Object item = event.getSource();
this.getChangeSupport().fireItemsReplaced(
new ListReplaceEvent(this, LIST_VALUES, CollectionTools.indexOf(this.listHolder, item), item, item));
}
@Override
protected ChangeSupport buildChangeSupport() {
return new LocalChangeSupport(this, ListChangeListener.class, ListValueModel.LIST_VALUES);
}
private class LocalChangeSupport extends SingleAspectChangeSupport {
public LocalChangeSupport(Model source, Class<? extends EventListener> validListenerClass, String validAspectName) {
super(source, validListenerClass, validAspectName);
}
@Override
public boolean fireItemsReplaced(ListReplaceEvent event) {
this.check(LIST_CHANGE_LISTENER_CLASS, event.getListName());
if (event.getItemsSize() != 0) {
this.fireItemsReplaced_(event);
return true;
}
return false;
}
}
}
}