/******************************************************************************* * 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.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.BorderFactory; import javax.swing.ButtonModel; import javax.swing.JCheckBox; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.border.TitledBorder; import org.eclipse.persistence.tools.workbench.framework.context.ApplicationContext; import org.eclipse.persistence.tools.workbench.framework.resources.ResourceRepository; import org.eclipse.persistence.tools.workbench.framework.uitools.SwingComponentFactory; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWModifiable; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWModifier; 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.ValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.ValueStatePropertyValueModelAdapter; import org.eclipse.persistence.tools.workbench.uitools.app.swing.CheckBoxModelAdapter; import org.eclipse.persistence.tools.workbench.uitools.app.swing.RadioButtonModelAdapter; final class ModifierComponentGroup { private ApplicationContext context; Verifier verifier; private PropertyValueModel modifierHolder; private ValueModel allowedModifiersHolder; private PropertyValueModel accessLevelHolder; // access modifiers private JPanel accessModifierPanel; JRadioButton publicAccessRadioButton; JRadioButton protectedAccessRadioButton; JRadioButton defaultAccessRadioButton; JRadioButton privateAccessRadioButton; // other modifiers private JPanel otherModifiersPanel; JCheckBox abstractCheckBox; JCheckBox finalCheckBox; JCheckBox nativeCheckBox; JCheckBox staticCheckBox; JCheckBox synchronizedCheckBox; JCheckBox transientCheckBox; JCheckBox volatileCheckBox; ModifierComponentGroup(Verifier verifier, ValueModel modifiableHolder, ApplicationContext context) { super(); this.context = context; this.verifier = verifier; this.modifierHolder = this.buildModifierAdapter(modifiableHolder); this.allowedModifiersHolder = this.buildAllowedModifiersAdapter(); this.accessLevelHolder = this.buildAccessLevelAdapter(); } // ********** initialization ********** protected PropertyValueModel buildModifierAdapter(ValueModel modifiableHolder) { return new PropertyAspectAdapter(modifiableHolder) { protected Object getValueFromSubject() { return ((MWModifiable) this.subject).getModifier(); } public String toString() { return "ModifierComponentGroup.buildModifierAdapter(ValueModel)"; } }; } private PropertyValueModel buildAllowedModifiersAdapter() { return new ValueStatePropertyValueModelAdapter(this.modifierHolder); } private PropertyValueModel buildAccessLevelAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.ACCESS_LEVEL_PROPERTY) { protected Object getValueFromSubject() { return ((MWModifier) this.subject).getAccessLevel(); } protected void setValueOnSubject(Object value) { ((MWModifier) this.subject).setAccessLevel((String) value); } public String toString() { return "ModifierComponentGroup.buildAccessLevelAdapter()"; } }; } // ********** access modifiers panel ********** JPanel getAccessModifiersPanel() { if (this.accessModifierPanel == null) { this.accessModifierPanel = this.buildAccessModifiersPanel(); } return this.accessModifierPanel; } private JPanel buildAccessModifiersPanel() { JPanel panel = new TitledPanel(this.resourceRepository().getString("accessModifiers")); panel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(this.resourceRepository().getString("accessModifiers")), BorderFactory.createEmptyBorder(0, 0, 5, 5) ) ); return panel; } private ButtonModel buildAccessLevelRadioButtonModelAdapter(String accessLevel) { return new RadioButtonModelAdapter(this.accessLevelHolder, accessLevel); } // ********** public ********** JRadioButton getPublicAccessRadioButton() { if (this.publicAccessRadioButton == null) { this.publicAccessRadioButton = this.buildPublicAccessRadioButton(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierPublicListener()); } return this.publicAccessRadioButton; } private JRadioButton buildPublicAccessRadioButton() { JRadioButton rb = SwingComponentFactory.buildRadioButton( "PUBLIC_ACCESS_MODIFIER", this.buildAccessLevelRadioButtonModelAdapter(MWModifier.PUBLIC), this.resourceRepository() ); rb.setEnabled(this.publicShouldBeEnabled()); return rb; } private PropertyChangeListener buildModifierPublicListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.publicAccessRadioButton.setEnabled(ModifierComponentGroup.this.publicShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierPublicListener()"; } }; } boolean publicShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetPublic(); } // ********** protected ********** JRadioButton getProtectedAccessRadioButton() { if (this.protectedAccessRadioButton == null) { this.protectedAccessRadioButton = this.buildProtectedAccessRadioButton(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierProtectedListener()); } return this.protectedAccessRadioButton; } private JRadioButton buildProtectedAccessRadioButton() { JRadioButton rb = SwingComponentFactory.buildRadioButton( "PROTECTED_ACCESS_MODIFIER", this.buildAccessLevelRadioButtonModelAdapter(MWModifier.PROTECTED), this.resourceRepository() ); rb.setEnabled(this.protectedShouldBeEnabled()); return rb; } private PropertyChangeListener buildModifierProtectedListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.protectedAccessRadioButton.setEnabled(ModifierComponentGroup.this.protectedShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierProtectedListener()"; } }; } boolean protectedShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetProtected(); } // ********** default ********** JRadioButton getDefaultAccessRadioButton() { if (this.defaultAccessRadioButton == null) { this.defaultAccessRadioButton = this.buildDefaultAccessRadioButton(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierDefaultListener()); } return this.defaultAccessRadioButton; } private JRadioButton buildDefaultAccessRadioButton() { JRadioButton rb = SwingComponentFactory.buildRadioButton( "DEFAULT_ACCESS_MODIFIER", this.buildAccessLevelRadioButtonModelAdapter(MWModifier.PACKAGE), this.resourceRepository() ); rb.setEnabled(this.defaultShouldBeEnabled()); return rb; } private PropertyChangeListener buildModifierDefaultListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.defaultAccessRadioButton.setEnabled(ModifierComponentGroup.this.defaultShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierDefaultListener()"; } }; } boolean defaultShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetPackage(); } // ********** private ********** JRadioButton getPrivateAccessRadioButton() { if (this.privateAccessRadioButton == null) { this.privateAccessRadioButton = this.buildPrivateAccessRadioButton(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierPrivateListener()); } return this.privateAccessRadioButton; } private JRadioButton buildPrivateAccessRadioButton() { JRadioButton rb = SwingComponentFactory.buildRadioButton( "PRIVATE_ACCESS_MODIFIER", this.buildAccessLevelRadioButtonModelAdapter(MWModifier.PRIVATE), this.resourceRepository() ); rb.setEnabled(this.privateShouldBeEnabled()); return rb; } private PropertyChangeListener buildModifierPrivateListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.privateAccessRadioButton.setEnabled(ModifierComponentGroup.this.privateShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierPrivateListener()"; } }; } boolean privateShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetPrivate(); } // ********** other modifiers panel ********** JPanel getOtherModifiersPanel() { if (this.otherModifiersPanel == null) { this.otherModifiersPanel = this.buildOtherModifiersPanel(); } return this.otherModifiersPanel; } private JPanel buildOtherModifiersPanel() { JPanel panel = new TitledPanel(this.resourceRepository().getString("otherModifiers")); panel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(this.resourceRepository().getString("otherModifiers")), BorderFactory.createEmptyBorder(0, 0, 5, 5) ) ); return panel; } // ********** abstract ********** JCheckBox getAbstractCheckBox() { if (this.abstractCheckBox == null) { this.abstractCheckBox = this.buildAbstractCheckBox(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierAbstractListener()); } return this.abstractCheckBox; } private JCheckBox buildAbstractCheckBox() { JCheckBox cb = SwingComponentFactory.buildCheckBox( "ABSTRACT_MODIFIER", new CheckBoxModelAdapter(this.buildAbstractAdapter()), this.resourceRepository() ); cb.setEnabled(this.abstractShouldBeEnabled()); return cb; } private PropertyValueModel buildAbstractAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.CODE_PROPERTY) { protected Object getValueFromSubject() { return Boolean.valueOf(((MWModifier) this.subject).isAbstract()); } protected void setValueOnSubject(Object value) { ((MWModifier) this.subject).setAbstract(((Boolean) value).booleanValue()); } public String toString() { return "ModifierComponentGroup.buildAbstractAdapter()"; } }; } private PropertyChangeListener buildModifierAbstractListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.abstractCheckBox.setEnabled(ModifierComponentGroup.this.abstractShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierAbstractListener()"; } }; } boolean abstractShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetAbstract(); } // ********** final ********** JCheckBox getFinalCheckBox() { if (this.finalCheckBox == null) { this.finalCheckBox = this.buildFinalCheckBox(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierFinalListener()); } return this.finalCheckBox; } private JCheckBox buildFinalCheckBox() { JCheckBox cb = SwingComponentFactory.buildCheckBox( "FINAL_MODIFIER", new CheckBoxModelAdapter(this.buildFinalAdapter()), this.resourceRepository() ); cb.setEnabled(this.finalShouldBeEnabled()); return cb; } private PropertyValueModel buildFinalAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.CODE_PROPERTY) { protected Object getValueFromSubject() { return Boolean.valueOf(((MWModifier) this.subject).isFinal()); } protected void setValueOnSubject(Object value) { boolean finalFlag = ((Boolean) value).booleanValue(); // verify the change if (ModifierComponentGroup.this.verifier.verifyFinalChange(finalFlag)) { ((MWModifier) this.subject).setFinal(finalFlag); } else { // revert the check-box ModifierComponentGroup.this.getFinalCheckBox().setSelected( ! finalFlag); } } public String toString() { return "ModifierComponentGroup.buildFinalAdapter()"; } }; } private PropertyChangeListener buildModifierFinalListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.finalCheckBox.setEnabled(ModifierComponentGroup.this.finalShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierFinalListener()"; } }; } boolean finalShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetFinal(); } // ********** native ********** JCheckBox getNativeCheckBox() { if (this.nativeCheckBox == null) { this.nativeCheckBox = this.buildNativeCheckBox(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierNativeListener()); } return this.nativeCheckBox; } private JCheckBox buildNativeCheckBox() { JCheckBox cb = SwingComponentFactory.buildCheckBox( "NATIVE_MODIFIER", new CheckBoxModelAdapter(this.buildNativeAdapter()), this.resourceRepository() ); cb.setEnabled(this.nativeShouldBeEnabled()); return cb; } private PropertyValueModel buildNativeAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.CODE_PROPERTY) { protected Object getValueFromSubject() { return Boolean.valueOf(((MWModifier) this.subject).isNative()); } protected void setValueOnSubject(Object value) { ((MWModifier) this.subject).setNative(((Boolean) value).booleanValue()); } public String toString() { return "ModifierComponentGroup.buildNativeAdapter()"; } }; } private PropertyChangeListener buildModifierNativeListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.nativeCheckBox.setEnabled(ModifierComponentGroup.this.nativeShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierNativeListener()"; } }; } boolean nativeShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetNative(); } // ********** static ********** JCheckBox getStaticCheckBox() { if (this.staticCheckBox == null) { this.staticCheckBox = this.buildStaticCheckBox(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierStaticListener()); } return this.staticCheckBox; } private JCheckBox buildStaticCheckBox() { JCheckBox cb = SwingComponentFactory.buildCheckBox( "STATIC_MODIFIER", new CheckBoxModelAdapter(this.buildStaticAdapter()), this.resourceRepository() ); cb.setEnabled(this.staticShouldBeEnabled()); return cb; } private PropertyValueModel buildStaticAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.CODE_PROPERTY) { protected Object getValueFromSubject() { return Boolean.valueOf(((MWModifier) this.subject).isStatic()); } protected void setValueOnSubject(Object value) { boolean staticFlag = ((Boolean) value).booleanValue(); // verify the change if (ModifierComponentGroup.this.verifier.verifyStaticChange(staticFlag)) { ((MWModifier) this.subject).setStatic(staticFlag); } else { // revert the check-box ModifierComponentGroup.this.getStaticCheckBox().setSelected( ! staticFlag); } } public String toString() { return "ModifierComponentGroup.buildStaticAdapter()"; } }; } private PropertyChangeListener buildModifierStaticListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.staticCheckBox.setEnabled(ModifierComponentGroup.this.staticShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierStaticListener()"; } }; } boolean staticShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetStatic(); } // ********** synchronized ********** JCheckBox getSynchronizedCheckBox() { if (this.synchronizedCheckBox == null) { this.synchronizedCheckBox = this.buildSynchronizedCheckBox(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierSynchronizedListener()); } return this.synchronizedCheckBox; } private JCheckBox buildSynchronizedCheckBox() { JCheckBox cb = SwingComponentFactory.buildCheckBox( "SYNCHRONIZED_MODIFIER", new CheckBoxModelAdapter(this.buildSynchronizedAdapter()), this.resourceRepository() ); cb.setEnabled(this.synchronizedShouldBeEnabled()); return cb; } private PropertyValueModel buildSynchronizedAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.CODE_PROPERTY) { protected Object getValueFromSubject() { return Boolean.valueOf(((MWModifier) this.subject).isSynchronized()); } protected void setValueOnSubject(Object value) { ((MWModifier) this.subject).setSynchronized(((Boolean) value).booleanValue()); } public String toString() { return "ModifierComponentGroup.buildSynchronizedAdapter()"; } }; } private PropertyChangeListener buildModifierSynchronizedListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.synchronizedCheckBox.setEnabled(ModifierComponentGroup.this.synchronizedShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierSynchronizedListener()"; } }; } boolean synchronizedShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetSynchronized(); } // ********** transient ********** JCheckBox getTransientCheckBox() { if (this.transientCheckBox == null) { this.transientCheckBox = this.buildTransientCheckBox(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierTransientListener()); } return this.transientCheckBox; } private JCheckBox buildTransientCheckBox() { JCheckBox cb = SwingComponentFactory.buildCheckBox( "TRANSIENT_MODIFIER", new CheckBoxModelAdapter(this.buildTransientAdapter()), this.resourceRepository() ); cb.setEnabled(this.transientShouldBeEnabled()); return cb; } private PropertyValueModel buildTransientAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.CODE_PROPERTY) { protected Object getValueFromSubject() { return Boolean.valueOf(((MWModifier) this.subject).isTransient()); } protected void setValueOnSubject(Object value) { ((MWModifier) this.subject).setTransient(((Boolean) value).booleanValue()); } public String toString() { return "ModifierComponentGroup.buildTransientAdapter()"; } }; } private PropertyChangeListener buildModifierTransientListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.transientCheckBox.setEnabled(ModifierComponentGroup.this.transientShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierTransientListener()"; } }; } boolean transientShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetTransient(); } // ********** volatile ********** JCheckBox getVolatileCheckBox() { if (this.volatileCheckBox == null) { this.volatileCheckBox = this.buildVolatileCheckBox(); this.allowedModifiersHolder.addPropertyChangeListener(ValueModel.VALUE, this.buildModifierVolatileListener()); } return this.volatileCheckBox; } private JCheckBox buildVolatileCheckBox() { JCheckBox cb = SwingComponentFactory.buildCheckBox( "VOLATILE_MODIFIER", new CheckBoxModelAdapter(this.buildVolatileAdapter()), this.resourceRepository() ); cb.setEnabled(this.volatileShouldBeEnabled()); return cb; } private PropertyValueModel buildVolatileAdapter() { return new PropertyAspectAdapter(this.modifierHolder, MWModifier.CODE_PROPERTY) { protected Object getValueFromSubject() { return Boolean.valueOf(((MWModifier) this.subject).isVolatile()); } protected void setValueOnSubject(Object value) { ((MWModifier) this.subject).setVolatile(((Boolean) value).booleanValue()); } public String toString() { return "ModifierComponentGroup.buildVolatileAdapter()"; } }; } private PropertyChangeListener buildModifierVolatileListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { ModifierComponentGroup.this.volatileCheckBox.setEnabled(ModifierComponentGroup.this.volatileShouldBeEnabled()); } public String toString() { return "ModifierComponentGroup.buildModifierVolatileListener()"; } }; } boolean volatileShouldBeEnabled() { return (this.modifier() != null) && this.modifier().canBeSetVolatile(); } // ********** misc ********** private ResourceRepository resourceRepository() { return this.context.getResourceRepository(); } private MWModifier modifier() { return (MWModifier) this.modifierHolder.getValue(); } // ********** member classes ********** /** * In some situations we want to verify with the user that * s/he wants to change a particular modifer. */ interface Verifier { boolean verifyFinalChange(boolean newModifierIsFinal); boolean verifyStaticChange(boolean newModifierIsStatic); Verifier NULL_INSTANCE = new Verifier() { public boolean verifyFinalChange(boolean newModifierIsFinal) { return true; } public boolean verifyStaticChange(boolean newModifierIsStatic) { return true; } }; } private class TitledPanel extends JPanel { private final String title; TitledPanel(String title) { super(); this.title = title; } public Dimension getPreferredSize() { Dimension size = super.getPreferredSize(); TitledBorder border = BorderFactory.createTitledBorder(this.title); Dimension borderSize = border.getMinimumSize(this); size.width = Math.max(size.width, borderSize.width + 5); // +5 is to make sure there is a gap between the right border and the text size.height = Math.max(size.height, borderSize.height); return size; } } }