blob: d534c23e8f39a4ff65694b2dd340a0e611a2a66a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 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.ui.internal.properties;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jpt.core.JpaDataSource;
import org.eclipse.jpt.core.JpaProject;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.internal.JpaModelManager;
import org.eclipse.jpt.core.internal.JptCoreMessages;
import org.eclipse.jpt.core.internal.facet.JpaLibraryProviderConstants;
import org.eclipse.jpt.core.internal.platform.JpaPlatformRegistry;
import org.eclipse.jpt.db.ConnectionAdapter;
import org.eclipse.jpt.db.ConnectionListener;
import org.eclipse.jpt.db.ConnectionProfile;
import org.eclipse.jpt.db.ConnectionProfileListener;
import org.eclipse.jpt.db.Database;
import org.eclipse.jpt.db.JptDbPlugin;
import org.eclipse.jpt.db.Schema;
import org.eclipse.jpt.db.ui.internal.DTPUiTools;
import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
import org.eclipse.jpt.ui.internal.JptUiMessages;
import org.eclipse.jpt.ui.internal.swt.BooleanButtonModelAdapter;
import org.eclipse.jpt.ui.internal.swt.ComboModelAdapter;
import org.eclipse.jpt.ui.internal.util.ControlEnabler;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringConverter;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;
import org.eclipse.jpt.utility.internal.model.value.AspectAdapter;
import org.eclipse.jpt.utility.internal.model.value.BufferedWritablePropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.CachingTransformationPropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.CollectionListValueModelAdapter;
import org.eclipse.jpt.utility.internal.model.value.CompositeCollectionValueModel;
import org.eclipse.jpt.utility.internal.model.value.CompositeListValueModel;
import org.eclipse.jpt.utility.internal.model.value.ExtendedListValueModelWrapper;
import org.eclipse.jpt.utility.internal.model.value.ListPropertyValueModelAdapter;
import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.utility.internal.model.value.PropertyCollectionValueModelAdapter;
import org.eclipse.jpt.utility.internal.model.value.PropertyListValueModelAdapter;
import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.SortedListValueModelAdapter;
import org.eclipse.jpt.utility.internal.model.value.TransformationWritablePropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.BufferedWritablePropertyValueModel.Trigger;
import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.utility.model.listener.ChangeListener;
import org.eclipse.jpt.utility.model.listener.CollectionChangeListener;
import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.utility.model.value.ListValueModel;
import org.eclipse.jpt.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
import org.eclipse.jst.common.project.facet.ui.libprov.LibraryFacetPropertyPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
public class JpaProjectPropertiesPage
extends LibraryFacetPropertyPage
{
public static final String PROP_ID= "org.eclipse.jpt.ui.jpaProjectPropertiesPage"; //$NON-NLS-1$
private WritablePropertyValueModel<IProject> projectHolder;
private PropertyValueModel<JpaProject> jpaProjectHolder;
private Trigger trigger;
private PropertyChangeListener validationListener;
private BufferedWritablePropertyValueModel<String> platformIdModel;
private BufferedWritablePropertyValueModel<String> connectionModel;
private ListValueModel<String> connectionChoicesModel;
private PropertyValueModel<ConnectionProfile> connectionProfileModel;
private BufferedWritablePropertyValueModel<Boolean> overrideDefaultSchemaModel;
private BufferedWritablePropertyValueModel<String> defaultSchemaModel;
private WritablePropertyValueModel<String> combinedDefaultSchemaModel;
private ListValueModel<String> schemaChoicesModel;
private BufferedWritablePropertyValueModel<Boolean> discoverAnnotatedClassesModel;
private WritablePropertyValueModel<Boolean> listAnnotatedClassesModel;
public JpaProjectPropertiesPage() {
super();
this.projectHolder = new SimplePropertyValueModel<IProject>();
this.jpaProjectHolder = initializeJpaProjectHolder();
this.trigger = new Trigger();
this.validationListener = initializeValidationListener();
this.platformIdModel = initializePlatformIdModel();
this.connectionModel = initializeConnectionModel();
this.connectionChoicesModel = initializeConnectionChoicesModel();
this.connectionProfileModel = initializeConnectionProfileModel();
this.overrideDefaultSchemaModel = initializeOverrideDefaultSchemaModel();
this.defaultSchemaModel = initializeDefaultSchemaModel();
this.combinedDefaultSchemaModel = initializeCombinedDefaultSchemaModel();
this.schemaChoicesModel = initializeSchemaChoicesModel();
this.discoverAnnotatedClassesModel = initializeDiscoverAnnotatedClassesModel();
this.listAnnotatedClassesModel = initializeListAnnotatedClassesModel();
}
protected PropertyValueModel<JpaProject> initializeJpaProjectHolder() {
return new JpaProjectHolder(this.projectHolder);
}
protected PropertyChangeListener initializeValidationListener() {
return new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
if (! JpaProjectPropertiesPage.this.getControl().isDisposed()) {
updateValidation();
}
}
};
}
protected BufferedWritablePropertyValueModel<String> initializePlatformIdModel() {
BufferedWritablePropertyValueModel<String> model =
new BufferedWritablePropertyValueModel(
new PlatformIdModel(this.jpaProjectHolder), this.trigger);
model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
model.addPropertyChangeListener(
PropertyValueModel.VALUE,
new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
JpaProjectPropertiesPage.this.getLibraryInstallDelegate().
setEnablementContextVariable(
JpaLibraryProviderConstants.EXPR_VAR_JPA_PLATFORM,
event.getNewValue());
}
});
return model;
}
protected BufferedWritablePropertyValueModel<String> initializeConnectionModel() {
BufferedWritablePropertyValueModel<String> model =
new BufferedWritablePropertyValueModel(
new ConnectionModel(this.jpaProjectHolder), this.trigger);
model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
return model;
}
protected ListValueModel<String> initializeConnectionChoicesModel() {
return new ExtendedListValueModelWrapper(
(String) null,
new SortedListValueModelAdapter(
new CollectionListValueModelAdapter(
new ConnectionChoicesModel(this.projectHolder))));
}
protected PropertyValueModel<ConnectionProfile> initializeConnectionProfileModel() {
return new CachingTransformationPropertyValueModel<String, ConnectionProfile>(this.connectionModel) {
@Override
protected ConnectionProfile transform_(String value) {
return JptDbPlugin.instance().getConnectionProfileFactory().buildConnectionProfile(value);
}
};
}
protected BufferedWritablePropertyValueModel<Boolean> initializeOverrideDefaultSchemaModel() {
BufferedWritablePropertyValueModel<Boolean> model =
new BufferedWritablePropertyValueModel(
new OverrideDefaultSchemaModel(this.jpaProjectHolder),
this.trigger);
model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
return model;
}
protected BufferedWritablePropertyValueModel<String> initializeDefaultSchemaModel() {
return new BufferedWritablePropertyValueModel(
new DefaultSchemaModel(this.jpaProjectHolder),
new DefaultSchemaTrigger(this.trigger, this.overrideDefaultSchemaModel));
}
protected WritablePropertyValueModel<String> initializeCombinedDefaultSchemaModel() {
WritablePropertyValueModel<String> model =
new CombinedDefaultSchemaModel(
this.defaultSchemaModel,
this.overrideDefaultSchemaModel,
new DefaultDefaultSchemaModel(this.connectionProfileModel));
model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
return model;
}
protected ListValueModel<String> initializeSchemaChoicesModel() {
Collection<CollectionValueModel> cvms = new ArrayList<CollectionValueModel>();
cvms.add(new PropertyCollectionValueModelAdapter(this.defaultSchemaModel));
cvms.add(new SchemaChoicesModel(this.connectionProfileModel));
return new SortedListValueModelAdapter(
new CompositeCollectionValueModel<CollectionValueModel, String>(cvms) {
@Override
public Iterator<String> iterator() {
Set<String> uniqueValues = new HashSet<String>();
for (String each : CollectionTools.iterable(super.iterator())) {
if (each != null) {
uniqueValues.add(each);
}
}
return uniqueValues.iterator();
}
});
}
protected BufferedWritablePropertyValueModel<Boolean> initializeDiscoverAnnotatedClassesModel() {
BufferedWritablePropertyValueModel<Boolean> model =
new BufferedWritablePropertyValueModel(
new DiscoverAnnotatedClassesModel(this.jpaProjectHolder), this.trigger);
model.addPropertyChangeListener(PropertyValueModel.VALUE, this.validationListener);
return model;
}
protected WritablePropertyValueModel<Boolean> initializeListAnnotatedClassesModel() {
return new TransformationWritablePropertyValueModel<Boolean, Boolean>(
this.discoverAnnotatedClassesModel) {
@Override
protected Boolean transform_(Boolean value) {
return ! value;
}
@Override
protected Boolean reverseTransform_(Boolean value) {
return ! value;
}
};
}
protected JpaProject getJpaProject() {
return this.jpaProjectHolder.getValue();
}
protected String getJpaPlatformId() {
return this.platformIdModel.getValue();
}
protected String getConnectionName() {
return this.connectionModel.getValue();
}
protected ConnectionProfile getConnectionProfile() {
// we just use the connection profile to log in, so go to the db plug-in
return JptDbPlugin.instance().getConnectionProfileFactory().
buildConnectionProfile(getConnectionName());
}
protected Boolean getOverrideDefaultSchema() {
return this.overrideDefaultSchemaModel.getValue();
}
protected List<String> getDefaultSchemaChoices() {
return CollectionTools.list(this.schemaChoicesModel.iterator());
}
protected String getDefaultSchema() {
return this.defaultSchemaModel.getValue();
}
@Override
public IProjectFacetVersion getProjectFacetVersion() {
final IProjectFacet jsfFacet = ProjectFacetsManager.getProjectFacet( "jpt.jpa" );
final IFacetedProject fproj = getFacetedProject();
return fproj.getInstalledVersion( jsfFacet );
}
@Override
protected LibraryInstallDelegate createLibraryInstallDelegate(
IFacetedProject project, IProjectFacetVersion fv) {
Map<String, Object> enablementVariables = new HashMap<String, Object>();
enablementVariables.put(
JpaLibraryProviderConstants.EXPR_VAR_JPA_PLATFORM, "");
return new LibraryInstallDelegate(project, fv, enablementVariables);
}
@Override
protected Control createPageContents(Composite parent) {
this.projectHolder.setValue(getProject());
Composite composite = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout(layout);
new PlatformGroup(composite);
Control libraryProviderComposite = super.createPageContents(composite);
libraryProviderComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
new ConnectionGroup(composite);
new PersistentClassManagementGroup(composite);
Dialog.applyDialogFont(composite);
PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE);
updateValidation();
return composite;
}
Button createButton(Composite container, int span, String text, int style) {
Button button = new Button(container, SWT.NONE | style);
button.setText(text);
GridData gd = new GridData();
gd.horizontalSpan = span;
button.setLayoutData(gd);
return button;
}
Combo createCombo(Composite container, int span, boolean fillHorizontal) {
Combo combo = new Combo(container, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
GridData gd;
if (fillHorizontal) {
gd = new GridData(GridData.FILL_HORIZONTAL);
}
else {
gd = new GridData();
}
gd.horizontalSpan = span;
combo.setLayoutData(gd);
return combo;
}
@Override
public boolean performOk() {
super.performOk();
final IWorkspaceRunnable wr = new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor)
throws CoreException {
performOkInternal(monitor);
}
};
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
try {
IWorkspace ws = ResourcesPlugin.getWorkspace();
ws.run(wr, ws.getRoot(), IWorkspace.AVOID_UPDATE, monitor);
}
catch(CoreException e) {
throw new InvocationTargetException(e);
}
}
};
try {
new ProgressMonitorDialog(getShell()).run(true, false, op);
}
catch (InterruptedException e) {
return false;
}
catch (InvocationTargetException e) {
final Throwable te = e.getTargetException();
throw new RuntimeException(te);
}
return true;
}
private void performOkInternal(IProgressMonitor monitor)
throws CoreException {
if (this.platformIdModel.isBuffering()) {
this.trigger.accept();
JpaModelManager.instance().rebuildJpaProject(getProject());
getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
}
else if (this.connectionModel.isBuffering()
|| this.defaultSchemaModel.isBuffering()
|| this.discoverAnnotatedClassesModel.isBuffering()) {
this.trigger.accept();
getProject().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
}
}
@Override
protected void performDefaults() {
super.performDefaults();
this.trigger.reset();
}
@Override
protected IStatus performValidation() {
Map<Integer, List<IStatus>> statuses = new HashMap<Integer, List<IStatus>>();
statuses.put(IStatus.ERROR, new ArrayList<IStatus>());
statuses.put(IStatus.WARNING, new ArrayList<IStatus>());
statuses.put(IStatus.INFO, new ArrayList<IStatus>());
statuses.put(IStatus.OK, CollectionTools.list(Status.OK_STATUS));
/* validate platform */
// user is unable to unset the platform, so no validation necessary
/* library provider */
IStatus lpStatus = super.performValidation();
statuses.get(lpStatus.getSeverity()).add(lpStatus);
/* validate connection */
String connectionName = getConnectionName();
ConnectionProfile connectionProfile = getConnectionProfile();
if (! StringTools.stringIsEmpty(connectionName)) {
if (connectionProfile == null) {
statuses.get(IStatus.ERROR).add(
buildErrorStatus(
NLS.bind(
JptCoreMessages.VALIDATE_CONNECTION_INVALID,
connectionName)));
}
if (! connectionProfile.isActive()) {
statuses.get(IStatus.INFO).add(
buildInfoStatus(
JptCoreMessages.VALIDATE_CONNECTION_NOT_CONNECTED));
}
}
/* default schema */
if (getOverrideDefaultSchema()) {
String defaultSchema = getDefaultSchema();
if (StringTools.stringIsEmpty(defaultSchema)) {
statuses.get(IStatus.ERROR).add(
buildErrorStatus(
JptCoreMessages.VALIDATE_DEFAULT_SCHEMA_NOT_SPECIFIED));
}
else if (connectionProfile != null
&& connectionProfile.isConnected()
&& ! getDefaultSchemaChoices().contains(defaultSchema)) {
statuses.get(IStatus.WARNING).add(
buildWarningStatus(
NLS.bind(
JptCoreMessages.VALIDATE_CONNECTION_DOESNT_CONTAIN_SCHEMA,
defaultSchema)));
}
}
if (! statuses.get(IStatus.ERROR).isEmpty()) {
return statuses.get(IStatus.ERROR).get(0);
}
else if (! statuses.get(IStatus.WARNING).isEmpty()) {
return statuses.get(IStatus.WARNING).get(0);
}
else if (! statuses.get(IStatus.INFO).isEmpty()) {
return statuses.get(IStatus.INFO).get(0);
}
else {
return statuses.get(IStatus.OK).get(0);
}
}
private IStatus buildInfoStatus(String message) {
return buildStatus(IStatus.INFO, message);
}
private IStatus buildWarningStatus(String message) {
return buildStatus(IStatus.WARNING, message);
}
private IStatus buildErrorStatus(String message) {
return buildStatus(IStatus.ERROR, message);
}
private IStatus buildStatus(int severity, String message) {
return new Status(severity, JptCorePlugin.PLUGIN_ID, message);
}
private static abstract class BasePropertyAspectAdapter<S, V>
extends AspectAdapter<S>
implements WritablePropertyValueModel<V>
{
/**
* Cache the current value so we can pass an old value when we fire a
* property change event
*/
protected V value;
protected BasePropertyAspectAdapter(PropertyValueModel<S> subjectHolder) {
super(subjectHolder);
this.value = null;
}
// ************ WritablePropertyValueModel impl ************************
@Override
public V getValue() {
return this.value;
}
public final void setValue(V value) {
if (this.subject != null) {
setValue_(value);
}
}
protected void setValue_(V value) {
throw new UnsupportedOperationException("setValue");
}
// ************ AspectAdapter impl *************************************
@Override
protected Class<? extends ChangeListener> getListenerClass() {
return PropertyChangeListener.class;
}
@Override
protected String getListenerAspectName() {
return VALUE;
}
@Override
protected boolean hasListeners() {
return hasAnyPropertyChangeListeners(VALUE);
}
@Override
protected void fireAspectChange(Object oldValue, Object newValue) {
firePropertyChanged(VALUE, oldValue, newValue);
}
@Override
protected void engageSubject_() {
this.value = buildValue();
}
@Override
protected void disengageSubject_() {
this.value = null;
}
@Override
public void toString(StringBuilder sb) {
sb.append(this.getValue());
}
// ************ internal ***********************************************
protected V buildValue() {
if (this.subject != null) {
return buildValue_();
}
return null;
}
protected abstract V buildValue_();
protected void valueChanged() {
V oldValue = this.getValue();
this.value = buildValue();
this.fireAspectChange(oldValue, this.getValue());
}
}
private abstract static class BaseCollectionAspectAdapter<S, E>
extends AspectAdapter<S>
implements CollectionValueModel<E>
{
protected BaseCollectionAspectAdapter(PropertyValueModel<? extends S> subjectHolder) {
super(subjectHolder);
}
// ************ ListValueModel impl ************************************
public Iterator<E> iterator() {
return this.subject == null ? EmptyIterator.<E>instance() : this.iterator_();
}
public int size() {
return this.subject == null ? 0 : this.size_();
}
// ************ AspectAdapter impl *************************************
@Override
protected Object getValue() {
return this.iterator();
}
@Override
protected Class<? extends ChangeListener> getListenerClass() {
return CollectionChangeListener.class;
}
@Override
protected String getListenerAspectName() {
return VALUES;
}
@Override
protected boolean hasListeners() {
return this.hasAnyCollectionChangeListeners(VALUES);
}
@Override
protected void fireAspectChange(Object oldValue, Object newValue) {
this.fireCollectionChanged(VALUES);
}
// ************ internal ***********************************************
protected Iterator<E> iterator_() {
throw new UnsupportedOperationException();
}
protected int size_() {
return CollectionTools.size(this.iterator());
}
protected void collectionChanged() {
this.fireCollectionChanged(VALUES);
}
}
private static class JpaProjectHolder
extends BasePropertyAspectAdapter<IProject, JpaProject>
{
/**
* Listens to the preferences to determine if the project's platform
* has changed, and is therefore a new JPA project
*/
private IPreferenceChangeListener platformChangeListener;
private JpaProjectHolder(PropertyValueModel<IProject> projectHolder) {
super(projectHolder);
this.platformChangeListener = buildPlatformChangeListener();
}
// ************ initialization *****************************************
private IPreferenceChangeListener buildPlatformChangeListener() {
return new IPreferenceChangeListener() {
public void preferenceChange(PreferenceChangeEvent event) {
if (JptCorePlugin.JPA_PLATFORM.equals(event.getKey())) {
JpaProjectHolder.this.valueChanged();
}
}
};
}
// ************ AspectAdapter impl *************************************
@Override
protected void engageSubject_() {
IEclipsePreferences preferences = JptCorePlugin.getProjectPreferences(this.subject);
preferences.addPreferenceChangeListener(this.platformChangeListener);
super.engageSubject_();
}
@Override
protected void disengageSubject_() {
IEclipsePreferences preferences = JptCorePlugin.getProjectPreferences(this.subject);
preferences.removePreferenceChangeListener(this.platformChangeListener);
super.disengageSubject_();
}
// ************ internal ***********************************************
@Override
protected JpaProject buildValue_() {
return JptCorePlugin.getJpaProject(this.subject);
}
}
private static class PlatformIdModel
extends BasePropertyAspectAdapter<JpaProject, String>
{
private PlatformIdModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
super(jpaProjectHolder);
}
// ************ WritablePropertyValueModel impl ************************
@Override
public void setValue_(String newPlatformId) {
JptCorePlugin.setJpaPlatformId(this.subject.getProject(), newPlatformId);
}
// ************ internal ***********************************************
@Override
protected String buildValue_() {
return JptCorePlugin.getJpaPlatformId(this.subject.getProject());
}
}
private final class PlatformGroup
{
private PlatformGroup(Composite composite) {
Group group = new Group(composite, SWT.NONE);
group.setText(JptUiMessages.JpaFacetWizardPage_platformLabel);
group.setLayout(new GridLayout());
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Combo platformCombo = createCombo(group, 1, true);
ComboModelAdapter.adapt(
buildPlatformChoicesListValueModel(),
JpaProjectPropertiesPage.this.platformIdModel,
platformCombo,
buildPlatformLabelConverter());
}
private ListValueModel<String> buildPlatformChoicesListValueModel() {
return new SimpleListValueModel(
CollectionTools.list(JpaPlatformRegistry.instance().jpaPlatformIds()));
}
private StringConverter<String> buildPlatformLabelConverter() {
return new StringConverter<String>() {
public String convertToString(String platformId) {
return JpaPlatformRegistry.instance().getJpaPlatformLabel(platformId);
}
};
}
}
private static class ConnectionModel
extends BasePropertyAspectAdapter<JpaProject, String>
{
private PropertyChangeListener connectionChangeListener;
private ConnectionModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
super(jpaProjectHolder);
this.connectionChangeListener = buildConnectionChangeListener();
}
// ************ initialization *****************************************
private PropertyChangeListener buildConnectionChangeListener() {
return new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
ConnectionModel.this.valueChanged();
}
};
}
// ************ WritablePropertyValueModel impl ************************
@Override
public void setValue_(String newConnection) {
this.subject.getDataSource().setConnectionProfileName(newConnection);
}
// ************ AspectAdapter impl *************************************
@Override
protected void engageSubject_() {
JpaDataSource dataSource = this.subject.getDataSource();
dataSource.addPropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_NAME_PROPERTY, this.connectionChangeListener);
super.engageSubject_();
}
@Override
protected void disengageSubject_() {
JpaDataSource dataSource = this.subject.getDataSource();
dataSource.removePropertyChangeListener(JpaDataSource.CONNECTION_PROFILE_NAME_PROPERTY, this.connectionChangeListener);
super.disengageSubject_();
}
// ************ internal ***********************************************
@Override
protected String buildValue_() {
return this.subject.getDataSource().getConnectionProfileName();
}
}
private static class ConnectionChoicesModel
extends BaseCollectionAspectAdapter<IProject, String>
{
private ConnectionProfileListener connectionProfileListener;
private ConnectionChoicesModel(PropertyValueModel<IProject> subjectHolder) {
super(subjectHolder);
this.connectionProfileListener = buildConnectionProfileListener();
}
// ************ initialization *****************************************
private ConnectionProfileListener buildConnectionProfileListener() {
return new ConnectionProfileListener() {
public void connectionProfileAdded(String name) {
collectionChanged();
}
public void connectionProfileRemoved(String name) {
collectionChanged();
}
public void connectionProfileRenamed(String oldName, String newName) {
// ignore this event for now. connecting a profile actually
// throws a connection renamed event, which messes up the
// list selection. there shouldn't be a connection renamed
// within the scope of this dialog anyhow.
// collectionChanged();
}
};
}
// ************ AspectAdapter impl *************************************
@Override
protected void engageSubject_() {
JptDbPlugin.instance().getConnectionProfileFactory().
addConnectionProfileListener(this.connectionProfileListener);
}
@Override
protected void disengageSubject_() {
JptDbPlugin.instance().getConnectionProfileFactory().
removeConnectionProfileListener(this.connectionProfileListener);
}
// ************ internal ***********************************************
@Override
protected Iterator<String> iterator_() {
return JptDbPlugin.instance().getConnectionProfileFactory().connectionProfileNames();
}
}
private static class OverrideDefaultSchemaModel
extends BasePropertyAspectAdapter<JpaProject, Boolean>
{
// the superclass "value" is the *cached* value
private Boolean actualValue;
private OverrideDefaultSchemaModel(PropertyValueModel<JpaProject> jpaProjectHolder) {
super(jpaProjectHolder);
}
// ************ WritablePropertyValueModel impl ************************
@Override
public Boolean getValue() {
Boolean value = super.getValue();
return (value == null) ? Boolean.FALSE : value;
}
@Override
public void setValue_(Boolean newValue) {
this.actualValue = newValue;
valueChanged();
}
// ************ AspectAdapter impl *************************************
@Override
protected void engageSubject_() {
this.actualValue = this.buildActualValue_();
super.engageSubject_();
}
@Override
protected void disengageSubject_() {
this.actualValue = null;
super.disengageSubject_();
}
// ************ internal ***********************************************
@Override
protected Boolean buildValue_() {
return this.actualValue;
}
protected Boolean buildActualValue_() {
return ! StringTools.stringIsEmpty(this.subject.getUserOverrideDefaultSchema());
}
}
private static class DefaultSchemaModel
extends PropertyAspectAdapter<JpaProject, String>
{
private DefaultSchemaModel(PropertyValueModel<JpaProject> jpaProjectModel) {
super(jpaProjectModel, JpaProject.USER_OVERRIDE_DEFAULT_SCHEMA_PROPERTY);
}
// ************ WritablePropertyValueModel impl ************************
@Override
public void setValue_(String newSchema) {
this.subject.setUserOverrideDefaultSchema(newSchema);
}
// ************ internal ***********************************************
@Override
protected String buildValue_() {
return this.subject.getUserOverrideDefaultSchema();
}
}
private static class DefaultDefaultSchemaModel
extends BasePropertyAspectAdapter<ConnectionProfile, String>
{
private ConnectionListener connectionListener;
private DefaultDefaultSchemaModel(
PropertyValueModel<ConnectionProfile> connectionProfileModel) {
super(connectionProfileModel);
this.connectionListener = buildConnectionListener();
}
// ************ initialization *****************************************
private ConnectionListener buildConnectionListener() {
return new ConnectionAdapter() {
@Override
public void opened(ConnectionProfile profile) {
if (profile.equals(DefaultDefaultSchemaModel.this.subject)) {
valueChanged();
}
}
@Override
public void schemaChanged(ConnectionProfile profile, Schema schema) {
if (profile.equals(DefaultDefaultSchemaModel.this.subject)) {
valueChanged();
}
}
};
}
// ************ AspectAdapter impl *************************************
@Override
protected void engageSubject_() {
this.subject.addConnectionListener(this.connectionListener);
super.engageSubject_();
}
@Override
protected void disengageSubject_() {
this.subject.removeConnectionListener(this.connectionListener);
super.disengageSubject_();
}
// ************ internal ***********************************************
@Override
protected String buildValue_() {
Database db = this.subject.getDatabase();
if (db == null) {
return null;
}
Schema schema = db.getDefaultSchema();
return (schema == null) ? null : schema.getIdentifier();
}
}
private static class CombinedDefaultSchemaModel
extends ListPropertyValueModelAdapter<String>
implements WritablePropertyValueModel<String>
{
private WritablePropertyValueModel<String> defaultSchemaModel;
private PropertyValueModel<Boolean> overrideDefaultSchemaModel;
private PropertyValueModel<String> defaultDefaultSchemaModel;
private CombinedDefaultSchemaModel(
WritablePropertyValueModel<String> defaultSchemaModel,
PropertyValueModel<Boolean> overrideDefaultSchemaModel,
PropertyValueModel<String> defaultDefaultSchemaModel) {
super(
new CompositeListValueModel(
CollectionTools.list(
new PropertyListValueModelAdapter<String>(defaultSchemaModel),
new PropertyListValueModelAdapter<Boolean>(overrideDefaultSchemaModel),
new PropertyListValueModelAdapter<String>(defaultDefaultSchemaModel)
)));
this.defaultSchemaModel = defaultSchemaModel;
this.overrideDefaultSchemaModel = overrideDefaultSchemaModel;
this.defaultDefaultSchemaModel = defaultDefaultSchemaModel;
}
// ************ ListPropertyValueModelAdapter impl *********************
@Override
protected String buildValue() {
if (this.overrideDefaultSchemaModel.getValue()) {
return this.defaultSchemaModel.getValue();
}
else {
return this.defaultDefaultSchemaModel.getValue();
}
}
// ************ WritablePropertyValueModel impl ************************
public void setValue(String value) {
if (this.overrideDefaultSchemaModel.getValue()) {
this.defaultSchemaModel.setValue(value);
}
propertyChanged();
}
}
private static class DefaultSchemaTrigger
extends Trigger
{
private Trigger parentTrigger;
private PropertyValueModel<Boolean> overrideDefaultSchemaModel;
private DefaultSchemaTrigger(
Trigger parentTrigger,
PropertyValueModel<Boolean> overrideDefaultSchemaModel) {
super();
this.parentTrigger = parentTrigger;
this.parentTrigger.addPropertyChangeListener(
VALUE,
new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
respondToParent();
}
});
this.overrideDefaultSchemaModel = overrideDefaultSchemaModel;
this.overrideDefaultSchemaModel.addPropertyChangeListener(
VALUE,
new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
respondToOverride();
}
});
}
protected void respondToParent() {
if (this.parentTrigger.isAccepted()) {
if (this.overrideDefaultSchemaModel.getValue()) {
accept();
}
}
else if (this.parentTrigger.isReset()) {
reset();
}
}
protected void respondToOverride() {
if (! this.overrideDefaultSchemaModel.getValue()) {
reset();
}
}
}
private static class SchemaChoicesModel
extends BaseCollectionAspectAdapter<ConnectionProfile, String>
{
private ConnectionListener connectionListener;
private SchemaChoicesModel(PropertyValueModel<ConnectionProfile> subjectHolder) {
super(subjectHolder);
this.connectionListener = buildConnectionListener();
}
// ************ initialization *****************************************
private ConnectionListener buildConnectionListener() {
return new ConnectionAdapter() {
@Override
public void opened(ConnectionProfile profile) {
if (profile.equals(SchemaChoicesModel.this.subject)) {
collectionChanged();
}
}
@Override
public void schemaChanged(ConnectionProfile profile, Schema schema) {
if (profile.equals(SchemaChoicesModel.this.subject)) {
collectionChanged();
}
}
};
}
// ************ AspectAdapter impl *************************************
@Override
protected void engageSubject_() {
this.subject.addConnectionListener(this.connectionListener);
}
@Override
protected void disengageSubject_() {
this.subject.removeConnectionListener(this.connectionListener);
}
// ************ internal ***********************************************
@Override
protected Iterator<String> iterator_() {
return (this.subject.getDatabase() == null) ?
EmptyIterator.<String>instance() :
this.subject.getDatabase().sortedSchemaIdentifiers();
}
}
private final class ConnectionGroup
{
private Link connectLink;
public ConnectionGroup(Composite composite) {
Group group = new Group(composite, SWT.NONE);
group.setText(JptUiMessages.JpaFacetWizardPage_connectionLabel);
group.setLayout(new GridLayout(3, false));
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.PROPERTIES_JAVA_PERSISTENCE_CONNECTION);
Combo connectionCombo = createCombo(group, 3, true);
ComboModelAdapter.adapt(
JpaProjectPropertiesPage.this.connectionChoicesModel,
JpaProjectPropertiesPage.this.connectionModel,
connectionCombo,
new StringConverter<String>() {
public String convertToString(String o) {
return (o == null) ?
JptUiMessages.JpaFacetWizardPage_none :
o;
}
});
Link connectionLink = new Link(group, SWT.NONE);
GridData data = new GridData(GridData.END, GridData.CENTER, false, false);
data.horizontalSpan = 2;
connectionLink.setLayoutData(data);
connectionLink.setText(JptUiMessages.JpaFacetWizardPage_connectionLink);
connectionLink.addSelectionListener(
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
openNewConnectionWizard();
}
}
);
connectLink = new Link(group, SWT.NONE);
data = new GridData(GridData.END, GridData.CENTER, false, false);
data.horizontalSpan = 2;
connectLink.setLayoutData(data);
connectLink.setText(JptUiMessages.JpaFacetWizardPage_connectLink);
updateConnectLink();
connectLink.addSelectionListener(
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
openConnectionProfile();
}
});
PropertyChangeListener linkUpdateListener = new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent event) {
updateConnectLink();
}
};
JpaProjectPropertiesPage.this.connectionModel.addPropertyChangeListener(
PropertyValueModel.VALUE,
linkUpdateListener);
Button overrideDefaultSchemaButton = createButton(
group, 3,
JptUiMessages.JpaFacetWizardPage_overrideDefaultSchemaLabel,
SWT.CHECK);
BooleanButtonModelAdapter.adapt(
JpaProjectPropertiesPage.this.overrideDefaultSchemaModel,
overrideDefaultSchemaButton);
Label defaultSchemaLabel = new Label(group, SWT.LEFT);
defaultSchemaLabel.setText(JptUiMessages.JpaFacetWizardPage_defaultSchemaLabel);
GridData gd = new GridData();
gd.horizontalSpan = 1;
defaultSchemaLabel.setLayoutData(gd);
Combo defaultSchemaCombo = createCombo(group, 1, true);
ComboModelAdapter.adapt(
JpaProjectPropertiesPage.this.schemaChoicesModel,
JpaProjectPropertiesPage.this.combinedDefaultSchemaModel,
defaultSchemaCombo);
new ControlEnabler(
JpaProjectPropertiesPage.this.overrideDefaultSchemaModel,
defaultSchemaLabel, defaultSchemaCombo);
}
private void openNewConnectionWizard() {
String connectionName = DTPUiTools.createNewConnectionProfile();
if (connectionName != null) {
JpaProjectPropertiesPage.this.connectionModel.setValue(connectionName);
}
}
private void openConnectionProfile() {
ConnectionProfile cp = JpaProjectPropertiesPage.this.getConnectionProfile();
if (cp != null) {
cp.connect();
}
updateConnectLink();
}
private void updateConnectLink() {
if (! getControl().isDisposed()) {
ConnectionProfile cp = getConnectionProfile();
this.connectLink.setEnabled((cp != null) && cp.isDisconnected());
}
}
}
private class DiscoverAnnotatedClassesModel
extends PropertyAspectAdapter<JpaProject, Boolean>
{
private DiscoverAnnotatedClassesModel(PropertyValueModel<JpaProject> jpaProjectModel) {
super(jpaProjectModel, JpaProject.DISCOVERS_ANNOTATED_CLASSES_PROPERTY);
}
// ************ WritablePropertyValueModel impl ************************
@Override
protected void setValue_(Boolean newValue) {
this.subject.setDiscoversAnnotatedClasses(newValue);
}
// ************ internal ***********************************************
@Override
protected Boolean buildValue_() {
return this.subject.discoversAnnotatedClasses();
}
}
private final class PersistentClassManagementGroup
{
public PersistentClassManagementGroup(Composite composite) {
Group group = new Group(composite, SWT.NONE);
group.setText(JptUiMessages.JpaFacetWizardPage_persistentClassManagementLabel);
group.setLayout(new GridLayout());
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
PlatformUI.getWorkbench().getHelpSystem().setHelp(group, JpaHelpContextIds.NEW_JPA_PROJECT_CONTENT_PAGE_CLASSPATH);
Button discoverClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_discoverClassesButton, SWT.RADIO);
BooleanButtonModelAdapter.adapt(
JpaProjectPropertiesPage.this.discoverAnnotatedClassesModel,
discoverClassesButton);
Button listClassesButton = createButton(group, 1, JptUiMessages.JpaFacetWizardPage_listClassesButton, SWT.RADIO);
BooleanButtonModelAdapter.adapt(
JpaProjectPropertiesPage.this.listAnnotatedClassesModel,
listClassesButton);
}
}
}