/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.mappingsplugin.ui.descriptor; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.Insets; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collection; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.SpinnerModel; import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContextHolder; import org.eclipse.persistence.tools.workbench.framework.ui.chooser.ClassChooserPanel; import org.eclipse.persistence.tools.workbench.framework.ui.view.AbstractPanel; import org.eclipse.persistence.tools.workbench.framework.uitools.SwingComponentFactory; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWClass; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWClassAttribute; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWClassRepository; import org.eclipse.persistence.tools.workbench.mappingsplugin.ui.meta.ClassChooserTools; import org.eclipse.persistence.tools.workbench.mappingsplugin.ui.meta.ClassRepositoryHolder; import org.eclipse.persistence.tools.workbench.uitools.ComponentEnabler; import org.eclipse.persistence.tools.workbench.uitools.app.PropertyAspectAdapter; import org.eclipse.persistence.tools.workbench.uitools.app.PropertyValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.TransformationPropertyValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.ValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.ValuePropertyPropertyValueModelAdapter; import org.eclipse.persistence.tools.workbench.uitools.app.swing.NumberSpinnerModelAdapter; final class ClassAttributeTypesPanel extends AbstractPanel { // **************** Variables ********************************************* private ValueModel attributeHolder; private PropertyValueModel attributeTypeHolder; private PropertyValueModel attributeTypeDimensionalityHolder; private PropertyValueModel attributeValueTypeHolder; private PropertyValueModel attributeKetTypeHolder; private PropertyValueModel attributeItemTypeHolder; private ClassRepositoryHolder classRepositoryHolder; private JLabel valueTypeLabel; private ClassChooserPanel valueTypeClassChooserPanel; private JLabel keyTypeLabel; private ClassChooserPanel keyTypeClassChooserPanel; private JLabel itemTypeLabel; private ClassChooserPanel itemTypeClassChooserPanel; // **************** Constructors ****************************************** ClassAttributeTypesPanel(ValueModel attributeHolder, WorkbenchContextHolder contextHolder) { super(contextHolder); this.attributeHolder = attributeHolder; this.attributeTypeHolder = this.buildAttributeTypeAdapter(); this.attributeTypeDimensionalityHolder = this.buildAttributeTypeDimensionalityAdapter(); this.attributeValueTypeHolder = this.buildAttributeValueTypeHolder(); this.attributeKetTypeHolder = this.buildAttributeKeyTypeHolder(); this.attributeItemTypeHolder = this.buildAttributeItemTypeHolder(); this.classRepositoryHolder = this.buildClassRepositoryHolder(); initializeLayout(); } // **************** Initialization **************************************** private PropertyValueModel buildAttributeTypeAdapter() { PropertyValueModel adapter = new PropertyAspectAdapter(this.attributeHolder, MWClassAttribute.TYPE_PROPERTY) { protected Object getValueFromSubject() { return ((MWClassAttribute) this.subject).getType(); } protected void setValueOnSubject(Object value) { ((MWClassAttribute) this.subject).setType((MWClass) value); } }; adapter.addPropertyChangeListener(ValueModel.VALUE, this.buildAttributeListener()); return new ValuePropertyPropertyValueModelAdapter(adapter, MWClass.NAME_PROPERTY); } private PropertyValueModel buildAttributeTypeDimensionalityAdapter() { PropertyValueModel adapter = new PropertyAspectAdapter(this.attributeHolder, MWClassAttribute.DIMENSIONALITY_PROPERTY) { protected Object getValueFromSubject() { return new Integer(((MWClassAttribute) this.subject).getDimensionality()); } protected void setValueOnSubject(Object value) { ((MWClassAttribute) this.subject).setDimensionality(((Integer) value).intValue()); } }; adapter.addPropertyChangeListener(ValueModel.VALUE, this.buildAttributeListener()); return adapter; } private PropertyChangeListener buildAttributeListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { ClassAttributeTypesPanel.this.updateAllTypeComponents(); } }; } private PropertyValueModel buildAttributeValueTypeHolder() { PropertyValueModel attributeTypeValueHolder = new PropertyAspectAdapter(this.attributeHolder, MWClassAttribute.VALUE_TYPE_PROPERTY) { protected Object getValueFromSubject() { return ((MWClassAttribute) this.subject).getValueType(); } protected void setValueOnSubject(Object value) { ((MWClassAttribute) this.subject).setValueType((MWClass) value); } }; attributeTypeValueHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildAttributeValueTypeListener()); return attributeTypeValueHolder; } private PropertyChangeListener buildAttributeValueTypeListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { ClassAttributeTypesPanel.this.updateAllTypeComponents(); } }; } private PropertyValueModel buildAttributeKeyTypeHolder() { return new PropertyAspectAdapter(this.attributeHolder, MWClassAttribute.KEY_TYPE_PROPERTY) { protected Object getValueFromSubject() { return ((MWClassAttribute) this.subject).getKeyType(); } protected void setValueOnSubject(Object value) { ((MWClassAttribute) this.subject).setKeyType((MWClass) value); } }; } private PropertyValueModel buildAttributeItemTypeHolder() { return new PropertyAspectAdapter(this.attributeHolder, MWClassAttribute.ITEM_TYPE_PROPERTY) { protected Object getValueFromSubject() { return ((MWClassAttribute) this.subject).getItemType(); } protected void setValueOnSubject(Object value) { ((MWClassAttribute) this.subject).setItemType((MWClass) value); } }; } private ClassRepositoryHolder buildClassRepositoryHolder() { return new ClassRepositoryHolder() { public MWClassRepository getClassRepository() { return ClassAttributeTypesPanel.this.getAttribute().getRepository(); } }; } private void initializeLayout() { // // Action: Create the panel // this.setBorder(BorderFactory.createTitledBorder(resourceRepository().getString("TYPE_PANEL_TITLE"))); GridBagConstraints constraints = new GridBagConstraints(); Collection components = new ArrayList(); // // Action: Create the type label // JLabel typeLabel = SwingComponentFactory.buildLabel("TYPE_LABEL", resourceRepository()); components.add(typeLabel); constraints.gridx = 0; constraints.gridy = 0; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.LINE_START; constraints.insets = new Insets(5, 5, 0, 5); this.add(typeLabel, constraints); // // Action: Create the type chooser // ClassChooserPanel typeChooserPanel = ClassChooserTools.buildPanel( this.attributeTypeHolder, this.classRepositoryHolder, ClassChooserTools.buildDeclarableNonVoidFilter(), typeLabel, this.getWorkbenchContextHolder() ); components.add(typeChooserPanel); constraints.gridx = 1; constraints.gridy = 0; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1; constraints.weighty = 0; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.CENTER; constraints.insets = new Insets(5, 5, 0, 5); this.add(typeChooserPanel, constraints); // // Action: Create the dimensionality label // JLabel dimensionalityLabel = SwingComponentFactory.buildLabel("DIMENSIONALITY_LABEL", this.resourceRepository()); components.add(dimensionalityLabel); constraints.gridx = 0; constraints.gridy = 1; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.LINE_START; constraints.insets = new Insets(5, 5, 5, 0); this.add(dimensionalityLabel, constraints); // // Action: Create the dimensionality spin button // JSpinner dimensionalitySpinButton = this.buildDimensionalitySpinner(); components.add(dimensionalitySpinButton); dimensionalityLabel.setLabelFor(dimensionalitySpinButton); constraints.gridx = 1; constraints.gridy = 1; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.LINE_START; constraints.insets = new Insets(5, 5, 5, 5); this.add(dimensionalitySpinButton, constraints); // // Action: Create the value type label // this.valueTypeLabel = SwingComponentFactory.buildLabel("VALUE_TYPE_LABEL", this.resourceRepository()); this.valueTypeLabel.setVisible(false); components.add(this.valueTypeLabel); constraints.gridx = 0; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.LINE_START; constraints.insets = new Insets(0, 5, 5, 5); this.add(this.valueTypeLabel, constraints); // // Action: Create the value type chooser // this.valueTypeClassChooserPanel = ClassChooserTools.buildPanel( this.attributeValueTypeHolder, this.classRepositoryHolder, ClassChooserTools.buildDeclarableReferenceFilter(), this.valueTypeLabel, this.getWorkbenchContextHolder() ); this.valueTypeClassChooserPanel.setVisible(false); components.add(this.valueTypeClassChooserPanel); constraints.gridx = 1; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1; constraints.weighty = 0; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.CENTER; constraints.insets = new Insets(0, 5, 5, 5); this.add(this.valueTypeClassChooserPanel, constraints); // // Action: Create the key type label // this.keyTypeLabel = SwingComponentFactory.buildLabel("MAP_KEY_TYPE_LABEL", this.resourceRepository()); this.keyTypeLabel.setVisible(false); components.add(this.keyTypeLabel); constraints.gridx = 0; constraints.gridy = 3; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.LINE_START; constraints.insets = new Insets(0, 5, 5, 5); this.add(this.keyTypeLabel, constraints); // // Action: Create the key type chooser // this.keyTypeClassChooserPanel = ClassChooserTools.buildPanel( this.attributeKetTypeHolder, this.classRepositoryHolder, ClassChooserTools.buildDeclarableReferenceFilter(), this.keyTypeLabel, this.getWorkbenchContextHolder() ); this.keyTypeClassChooserPanel.setVisible(false); components.add(this.keyTypeClassChooserPanel); constraints.gridx = 1; constraints.gridy = 3; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1; constraints.weighty = 0; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.CENTER; constraints.insets = new Insets(0, 5, 5, 5); this.add(this.keyTypeClassChooserPanel, constraints); // // Action: Create the item type label // this.itemTypeLabel = SwingComponentFactory.buildLabel("ELEMENT_TYPE_LABEL", resourceRepository()); this.itemTypeLabel.setVisible(false); components.add(this.itemTypeLabel); constraints.gridx = 0; constraints.gridy = 4; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.LINE_START; constraints.insets = new Insets(0, 5, 5, 5); this.add(this.itemTypeLabel, constraints); // // Action: Create the item type chooser // this.itemTypeClassChooserPanel = ClassChooserTools.buildPanel( this.attributeItemTypeHolder, this.classRepositoryHolder, ClassChooserTools.buildDeclarableReferenceFilter(), this.itemTypeLabel, this.getWorkbenchContextHolder() ); this.itemTypeClassChooserPanel.setVisible(false); components.add(this.itemTypeClassChooserPanel); constraints.gridx = 1; constraints.gridy = 4; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1; constraints.weighty = 0; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.CENTER; constraints.insets = new Insets(0, 5, 5, 5); this.add(this.itemTypeClassChooserPanel, constraints); new ComponentEnabler(this.buildAttributeTypeBooleanHolder(), components); this.addHelpTopicId(this, this.helpTopicId()); } private ValueModel buildAttributeTypeBooleanHolder() { return new TransformationPropertyValueModel(this.attributeTypeHolder) { protected Object transform(Object value) { return value == null ? Boolean.FALSE : Boolean.TRUE; } }; } private String helpTopicId() { return "descriptor.classInfo.attributes.general.typeInfo"; } //***************** Dimensionality **************************************** private JSpinner buildDimensionalitySpinner() { JSpinner spinner = new JSpinner(this.buildDimensionalitySpinnerModel()); spinner.setPreferredSize(new Dimension(50, spinner.getPreferredSize().height)); return spinner; } private SpinnerModel buildDimensionalitySpinnerModel() { return new NumberSpinnerModelAdapter(this.attributeTypeDimensionalityHolder, new Integer(0), null, new Integer(1), new Integer(0)); } // **************** Behavior ********************************************** void updateAllTypeComponents() { this.updateValueTypeComponents(); this.updateItemTypeComponents(); this.updateKeyTypeComponents(); } private void updateValueTypeComponents() { boolean canChooseValueType = this.getAttribute() != null && this.getAttribute().canHaveValueType(); this.valueTypeLabel.setVisible(canChooseValueType); this.valueTypeClassChooserPanel.setVisible(canChooseValueType); } private void updateItemTypeComponents() { MWClassAttribute attribute = this.getAttribute(); boolean canChooseItemType = attribute != null && attribute.canHaveItemType(); this.itemTypeLabel.setVisible(canChooseItemType); this.itemTypeClassChooserPanel.setVisible(canChooseItemType); if (attribute != null && attribute.canHaveMapKeyAndValueTypes()) { this.itemTypeLabel.setText(resourceRepository().getString("MAP_VALUE_TYPE_LABEL")); this.itemTypeLabel.setDisplayedMnemonic(resourceRepository().getMnemonic("MAP_VALUE_TYPE_LABEL")); } else { this.itemTypeLabel.setText(resourceRepository().getString("ELEMENT_TYPE_LABEL")); this.itemTypeLabel.setDisplayedMnemonic(resourceRepository().getMnemonic("ELEMENT_TYPE_LABEL")); } } private void updateKeyTypeComponents() { boolean canChooseKeyType = this.getAttribute() != null && this.getAttribute().canHaveKeyType(); this.keyTypeLabel.setVisible(canChooseKeyType); this.keyTypeClassChooserPanel.setVisible(canChooseKeyType); } // **************** Convenience ******************************************* MWClassAttribute getAttribute() { return (MWClassAttribute) this.attributeHolder.getValue(); } }