| /******************************************************************************* |
| * 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.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.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.ui.libprov.FacetLibraryPropertyPage; |
| 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 FacetLibraryPropertyPage |
| { |
| 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); |
| 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 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 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 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) { |
| JptCorePlugin.setConnectionProfileName(this.subject.getProject(), 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 JptCorePlugin.getConnectionProfileName(this.subject.getProject()); |
| } |
| } |
| |
| |
| 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); |
| |
| 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() { |
| 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); |
| } |
| } |
| } |